浅析.Net下的AppDomain编程
我们知道,进程是操作系统用于隔离众多正在运行的应用程序的机制。在.Net之前,每一个应用程序被加载到单独的进程中,并为该进程指定私有的虚拟内存。进程不能直接访问物理内存,操作系统通过其它的处理把这些虚拟内存映射到物理内存或IO设备的某个区域,而这些物理内存之间不会有重叠,这就决定了一个进程不可能访问分配给另一个进程的内存。相应地,运行在该进程中的应用程序也不可能写入另一个应用程序的内存,这确保了任何执行出错的代码不会损害其地址空间以外的应用程序。在这种机制下,进程作为应用程序之间一个独立而安全的边界在很大程度上提高了运行安全。
进程的缺点是降低了性能。许多一起工作的进程需要相互通信,而进程却不能共享任何内存,你不能通过任何有意义的方式使用从一个进程传递到另一个进程的内存指针。此外,你不能在两个进程间进行直接调用。你必须代之以使用代理,它提供一定程度的间接性。虽然,使用动态连接库dll让所有的组件运行在同一空间,一定程度上可以提高性能,但这些组件相互影响,一个组件的错误将极有可能导致整个应用程序的崩溃,“dll地狱”更是让许多应用程序难以避免。
在.Net中,应用程序有了一个新的边界:应用程序域(以下简称域)。它是一个用于隔离应用程序的虚拟边界。为了禁止不应交互的代码进行交互,这种隔离是必要的。.Net的应用程序在域层次上进行隔离,一个域中的应用程序不能直接访问另一个域中的代码和数据。这种隔离使得在一个应用程序范围内创建的所有对象都在一个域内创建,确保在同一进程中一个域内运行的代码不会影响其他域内的应用程序,大大提高了运行的安全。
.Net结构中,由于公共语言运行库能够验证代码是否为类型安全的代码,所以它可以提供与进程边界一样大的隔离级别,其性能开销也要低得多。你可以在单个进程中运行几个域,而不会造成进程间调用或切换等方面的额外开销。这种方法是把任何一个进程分解到多个域中,允许多个应用程序在同一进程中运行,每个域大致对应一个应用程序,运行的每个线程都在一个特殊的域中。如果不同的可执行文件都运行在同一个进程空间中,它们就能轻松地共享数据或直接访问彼此的数据。这种代码同运行同一个进程但域不同的类型安全代码一起运行时是安全的。在一个进程内运行多个应用程序的能力显著增强了服务器的可伸缩性。
域是.Net 带来的一个重要改进,它不仅将众多在运行的应用程序隔离开来,还不影响彼此间通信。虽然,公共语言运行库禁止在不同域中的对象之间进行直接调用,但我们可以复制这些对象,或通过代理访问这些对象。如果以前一种方式,那么对该对象的调用为本地调用。也就是说,调用方和被引用的对象位于同一域中。如果通过代理访问对象,调用方和被引用的对象位于不同的域中,对该对象的调用被视为远程调用,这种情形与两个进程间的调用或两台计算机间的调用结构大致相同。这时,需要被引用对象的元数据对于两个域均可用,以便.Net即时编译JIT能正确执行。
在.Net中,线程是公共语言运行库用来执行代码的操作系统构造。在运行时,所有托管代码均加载到一个域中,由特定的操作系统线程来运行。然而,域和线程之间并不具有一一对应关系。在任意给定时间,单个域中可以执行不止一个线程,而且特定线程也并不局限在单个域内。也就是说,线程可以跨越域边界,不为每个域创建新线程。当然,在指定时刻,每一线程都只能在一个域中执行。运行库会跟踪所有域中有哪些线程正在运行。通过调用.Net类库的 Thread.GetDomain 方法,你还可以确定正在执行的线程所在的域。
作为公共语言运行库的隔离单元,域在进程中创建和运行。.Net结构中,运行时宿主(也叫作运行时主机)是负责将运行时载入进程并在域中执行用户代码和托管代码的应用程序。运行时宿主包括ASP.Net、浏览器Internet Explorer 和 Windows等外壳程序,负责创建进程和默认域,例如,Asp.Net为每个运行在web服务器上的web应用程序创建一个域。浏览器Internet explore创建运行受管制控件的域。
对多数应用程序,你并不必须创建相应的域,每次CLR在初始化一个进程时,将创建默认域,并使该进程运行于这个默认域下。然而,默认域不能由任何系统调用来卸载,该域只有在进程被卸载之后才能被销毁。如果直接在默认域下编程或运行代码,而由于某种原因域的代码崩溃了,那么就有使得整个服务随之崩溃的风险。
于是,针对不同的应用程序,应该创建和配置相应的域并载入适当的程序集。.Net为此提供了丰富的类库。其中,AppDomain 类是域的编程接口,其大量的(重载)方法能完成以下任务:
· 创建域
· 在域中加载程序集和类型
· 枚举域中的程序集和线程
· 卸载域
创建新域时,使用AppDomain 类的静态方法CreateDomain。你可以为域命名并按该名称来引用域。下面的示例语句创建新域,并为它指定名称 MyDomain:
AppDomain myDomain = AppDomain.CreateDomain("MyDomain"); |
然后你可以查询当前域的名称和新创建子域的名称:
string hostDomain=AppDomain.CurrentDomain.FriendlyName; string childDomain=myDomain.FriendlyName; |
在这里,属性FriendlyName表示的是域的友好名称,友好名称通过从程序集的基本代码中去除目录路径而形成。例如,文件名为 "d:/MyAppDomain/MyAssembly.exe" 的程序集加载到默认域中,域的友好名称就是 "MyAssembly.exe"。
更一般的是,在创建域之前,先设置好域的参数,这可以通过类AppDomainSetup来完成。该类的ApplicationBase 属性定义应用程序的根目录, AppDomainSetup 类还有一个极重要的属性变量LoaderOptimizzation,取值可以是MultiDomain,MultiDomainHost和SignleDomain等,用以指定被加载程序集的类别(共享程序集或域专用程序集),例如,以下语句把程序集设置为域专用程序集:
appDomainSetup.LoaderOptimization=LoaderOptimizatiion.SigleDomain; |
对以上两个方面简单归纳一下,对域的典型操作就包括:设置参数然后创建两个步骤,语句示例如下:
AppDomainSetup appDomainSetup=new AppDomainSetup();//实例化域设置 appDomainSetup.LoaderOptimization=LoaderOptimization.SingleDomain; //指定域类别 AppDoman ad=AppDomain.CreateDomain(domainName,appDomainSetup); //创建域 ... //应用程序在这里运行代码 ... AppDomain.Unload(ad);//卸载域 |
当使用完域时,可使用AppDomain类Unload()静态方法将其卸载。要卸载进程中在运行的托管代码,只能卸载代码运行时所在的域而不能卸载单独的程序集或类型,Unload方法会正常关闭指定的域。这时,载入域的所有程序集都会被移除,并且无法再使用。不过,如果域中的程序集对域是非特定的(域无关程序集,也即共享程序集),则程序集的数据还会保留在内存中,直至整个进程关闭。除了关闭整个进程,没有机制可以卸载这类程序集。由于一个进程中允许包含多个域,某个域可以在不停止整个进程的情况下卸载。以这样的方式卸载不再需要的代码,可以减少内存占用并极大提高应用程序的可缩放性。此外,由于线程并不与域一一对应,当域中存在活动线程时,调用AppDomain.Unload方法可能无法将域卸载并导致异常。
从上面的论述不难看出:要运行应用程序,必须首先将程序集(.Net下经编译产生,包含IL中间语言、元数据及清单等)加载到域中。而且一个域中可装载多个程序集。默认情况下,公共语言运行库自动将一个程序集加载到包含引用该程序集的代码的域。通过此方法,该程序集的代码和数据独立于使用该程序集的应用程序。
自行创建域的好处之一便是可以指定如何装载程序集。在域中有以下两种方式加载程序集:
1、将当前程序集加载入单独的域中,同一个程序集可能有多个副本;
2、以非特定于域的形式加载程序集,让一个程序集在多个域间共享;
这两种方式各自偏重于安全性和性能,需要视具体情况在二者之间权衡。具体地,在 .Net 框架中,System.Reflection.Assembly 类提供以下静态方法将程序集加载至域:
· Load()在给顶程序集名称的前提下,加载该程序集:
Assembly SampleAssembly; … SampleAssembly = Assembly.Load("System.Data");//根据类型加载程序集 |
· LoadFrom()在已知程序集文件名或路径等信息的情况下加载程序集:
Assembly SampleAssembly; … SampleAssembly = Assembly.LoadFrom("c://Sample.Assembly.dll");//根据已有程序集名称加载 |
参考资料:
《Microsoft .NET Framework程序设计》《.NET Framework高级编程》《.NET框架精髓 》等
相关文章:
AI 医生正式上岗了?AI 医疗结合迎爆发点!
作者 | 硬核云顶宫责编 | 晋兆雨封图 | CSDN 付费下载自视觉中国这些年,人工智能应用于医学界是非常热的话题。在医学三大杂志——新英格兰医学杂志、柳叶刀、JAMA上,AI与医疗相结合的论文,占比越来越高。其中最明显的趋势是将医生从繁重的诊…

Android之解析Android Map地图返回的Json数据
先上一下需要解析的Json数据:{"results" : [{"address_components" : [{"long_name" : "荔湾区","short_name" : "荔湾区","types" : [ "sublocality", "political" ]}…

9成P2P平台面临出局,千亿资本何去何从?
【阅读原文】作者:楠沨据研究院数据中心统计,截至2016年10月底,我国 P2P贷款余额已经攀升至7,470亿元左右,环比增长6.0%。进入10月份百强榜的平台,其贷款余额总计3,275亿元,占到整个行业的44%;榜…
关于Transformer,那些的你不知道的事
作者 | 小莫来源 | 阿泽的学习笔记(ID: aze_learning)引言本博客主要是本人在学习 Transformer 时的「所遇、所思、所解」,通过以 「十六连弹」 的方式帮助大家更好的理解该问题。十六连弹为什么要有 Transformer?Transformer 作用是什么&am…

用ASP.NET上传大文件
作者:思归 微软MVP http://blog.joycode.com/saucer/我们在上传大文件时都遇到过这样或那样的问题。设置很大的maxRequestLength值并不能完全解决问题,因为ASP.NET会block直到把整个文件载入内存后,再加以处理。实际上,如果…

中国最齐全的主要电子商务网站(B2C)
中国最齐全的主要电子商务网站(B2C)------[连载之电子商务网站架构]访问量超过100万的电子商务网站技术架构版本:V1出处:http://jimmyli.blog.51cto.com/ 我站在巨人肩膀上Jimmy Li作者:Jimmy Li关键词:中国 电子商务 网站 B2C连接…

怎么安装MYSQL5.0的JDBC驱动
1、下载mysql for jdbc driver. http://dev.mysql.com/downloads/connector/j/3.1.htmlMySQL Connector/J is distributed as a .zip or .tar.gz archive containing the sources and class files as well as a class-file only "binary" .jar archive named "…

ASP.NET中的事务处理和异常处理
刘彦青编译 来自:yesky 使用SQL-Transaction类和.NET提供的异常处理机制,我们就能够以一种可靠的方式处理数据库运行中的问题和发现系统异常。这篇小文章将解释事务处理和异常处理的概念和用法。 什么是事务? 事务处理是由以一个单一的…
2020年AI产业报告:100个岗位抢1个人,计算机视觉成最大缺口
“你永远都不知道明天和‘公司的意外’哪个先来。”疫情期间,这是我们最战战兢兢的心情。但是显然,有些人体会不了。这份行业数据,让笔者“柠檬”了。1疫情下,有的公司宣布破产有的公司增长413%疫情期间,人工智能的价值…

.NET Winform也能画出类似QQ、飞信这样的窗口风格和控件效果
MPN企业宝智能升级程序界面采用.NET的Winform技术,并没有延续企业宝主程序的绘制界面技术——WPF。直接采用Winform实现类似QQ和飞信的窗口风格比较困难,WPF好在还有一个Blend设计工具,而Winform只能靠自己一个一个像素去对齐、去仔细看&…

【转】HashMap、TreeMap、Hashtable、HashSet和ConcurrentHashMap区别
转自:http://blog.csdn.net/paincupid/article/details/47746341 一、HashMap和TreeMap区别 1.HashMap是基于散列表实现的,时间复杂度平均能达到O(1)。 TreeMap基于红黑树(一种自平衡二叉查找树)实现的,时间复杂度平均…

ASP.NET实现数据图表
作者:马金虎 来自:yesky 在ASP中插入图表,常用的方法是使用MSChart控件。那么在ASP.NET是否也是这样呢?答案是不可以的。 我们知道ASP.NET是一种编译语言,当客户端第一次调用ASP.NET页面的时候,其实是经过了一种…

Struts2基础(1)_MVC
2019独角兽企业重金招聘Python工程师标准>>> Struts2是有传统的Struts1和WebWork两个经典MVC框架发展起来,无论从Struts2的设计角度或则实际项目中的易用性来开,它都是一个非常优秀的MVC框架。 MVC的理解:MVC思想将应用中各组件按…
我发现了个Python黑魔法,执行任意代码都会自动念上一段「平安经」
来源 | Python编程时光最近的"平安经"可谓是引起了不小的风波啊。作为一个正儿八经的程序员,最害怕的就是自己的代码上线出现各种各样的 BUG。为此,明哥今天分享一个 Python 的黑魔法,教你如何在你执行任意 Python 代码前ÿ…

Java第一天学习笔记整理
一、关键字 java的关键字对java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等,关键字不能用作变量名、方法名、类名、包名。 常见的关键字: 用于定义数据类型的关键字 class interface byte short int lon…

ASP.NET中树形图的实现
来自:DotNET中文技术网 树形图用于显示按照树形结构进行组织的数据,其用途比较广泛,如计算机中的文件系统(Windows中的资源管理器)、企业或公司的组成结构等。我们知道在Windows下VB、PB、Delphi等工具提供了一个功能很强的树型控件TreeView…

同步你的手机联系人
从web1.0到2.0,我们进入了一个新的互联网时代移动时代.相信你的手机中,有许多联系人信息,你肯定不想把他们弄丢吧,像我之前隔一段时间就备份下,存到电脑中.现在再也不怕联系人信息丢了,只需要一个账户,同步一下,所有联系人信息都回来了.我是在Android智能手机上操作的,IOS就不清…
AI 技术发展飞快,高校 AI 教师的知识储备能满足学生旺盛的求知欲吗?
2019 年,AI 技术以惊人的速度发展;2020 年,AI 技术成熟的时机已经到来,随之而来的,是越来越旺盛的 AI 人才需求。近日,国家正式发布了一份《2020 年人工智能产业人才发展报告》显示,2020 年人工…

Windows Server 2008 R2安装子域控制器
一、实验网络拓扑图: 二、实验说明: 子域控制器安装前需要先把主域控制器安装好,然后子域控制器的DNS先指向主域控制器的IP地址 192.168.10.30,主域控制器委派DNS给子域控制器后再把子域控制器DNS指向自己的IP地址 192.168.10.31即…

使用嵌套的Repeater控件显示分级数据
作者:wincheer 来自:Asp.Net中文专业网 简介 本文描述如何使用嵌套的Repeater 控件来显示分级数据 。当然了,你也可以将这一技术应用到其他的列表绑定控件上去,比如DataGrid包含DataGrid,DataList包含DataList等等…
我还没考试,算法就说我的物理一定挂科
来源 | HyperAI超神经责编 | Carol封图 | CSDN 下载自视觉中国大学物理是理工科学生的基础必修课程,但也因为有一定的难度,令很多学生望而生畏。研究人员提出了用 AI 算法预测,哪些学生物理课有挂科风险,好让老师更好地进行教学指…

Dorado7功能及技术特点
简介 Dorado PresentationMiddleware(即Dorado展现中间件,以下简称Dorado)致力于辅助Web应用中表现层的开发过程。Dorado主要可以为您带来如下两方面的使用价值: 更加美观、更加人性化的Web操作界面。更加高效的表现层开发…

ELK日志分析平台搭建全过程
一、使用背景 当生产环境有很多服务器、很多业务模块的日志需要每时每刻查看时 二、环境 系统:centos 6.5 JDK:1.8 Elasticsearch-5.0.0 Logstash-5.0.0 kibana-5.0.0 三、安装 1、安装JDK 下载JDK:http://www.oracle.com/technetwork/java/j…

Android中Handler
本文通过例子来验证和说明使用Handler对象开启的线程是否和主线程为在同一线程中。 程序结构图如下: [1] HandlerActivity.java中的源码如下: [html] view plaincopyprint?package com.andyidea.handlerdemo2; import android.app.Activity; import…
刚出炉!程序员人才补贴:单项目最高补贴1000万元
最近,程序员届有一个重大好消息,可能很多人还不知道,那就是:国内某些城市已经开始程序员人才补贴了!对于人工智能公司的项目开发、人才引进、科技研发,最高按照国拨经费的30%给予配套支持,单个项…

ASP.NET中在线用户统计
天极论坛 统计在线用户的作用不言而喻,就是为了网站管理者可以知道当前用户的多少,然后根据用户数量来观察服务器或者程序的性能,从而可以直观的了解到网站的吸引力或者网站程序的效率。现在,我们就介绍一个简单明了的方法来统计…

数(Number)
--读《自然数原本:数数论》(薛海明,山西科学技术出版社)和《数论概论》([美]Joseph H.Silverman,机械工业出版社)笔记 人们对于数的认识从数数(counting)开始,…

linux 中root用户与普通用户的切换
su是在用户间切换,可以是从普通用户切换到root用户,也可以是从root用户切换到普通用户。 如果当前是root用户,那么切换成普通用户test用以下命令:su test或su - test 如果要切换回root用户或普通用户切换至root用户,用…
2个月做出一款AI项目?这些学生在DeeCamp上决出两个总冠军
出品 | AI科技大本营(ID:rgznai100)2个月,一群来自世界各地高校的学生做出了技术与商业化兼具的AI落地项目。8月5日,DeeCamp 2020人工智能训练营迎来总冠军答辩暨结营典礼。最终,自动驾驶赛道和创新赛道的两支团队夺得…

C语言宏定义技巧
C语言宏定义技巧(常用宏定义) 写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性等等。下面列举一些成熟软件中常用得宏定义。 1、防止一个头文件被重复包含 …