zoukankan      html  css  js  c++  java
  • 寄宿(host)和应用程序域(appdomain)

         寄宿和CLR

          寄宿允许任何Windows应用程序使用公共语言运行库(CLR)的特征。它允许已有的应用程序至少局部使用托管代码编写。它为应用程序提供了通过编程支持自定义和可扩展性的能力。

          在开发CLR时,微软实际上将CLR作为一个COM服务器实现在一个DLL内。微软为CLR定义了一个标准的COM接口,并且为该接口和COM服务器分配了GUID。安装.NET Framework时,表示CLR的COM服务器就像其他的COM服务器一样别注册到Windows的注册表里。详细信息可以看C++头文件MSCorEE.H。在这个头文件里定义了一些GUID和非托管的ICorRuntimeHost接口定义。

          任何Windows应用程序都可以寄宿CLR。非托管应用程序宿主调用CorBindToRuntimeEx函数或者另一个相似的函数来创建CLR COM的实例。CorBindToRuntimeEx函数在MSCorEE.dll文件中实现。该DLL被称为“垫片”(shim)。他的职责是判断创建何种版本的CLR,但他本是不包含CLR COM服务器。

         一台机器可以安装多个版本的CLR,但在机器中只有一个版本的MSCorEE.dll文件。安装在机器上的MSCorEE.dll的版本是那个随安装在机器上的最新版本的CLR一起发布的MSCorEE.dll的版本。它可以直到如何查找安装在机器上的任何一个以前版本的CLR。CLR本身并不在MECorEE.dll文件中实现,它在一个MSCorWks.dll文件中实现。

        Windows进程完全不必加载CLR,只有需要在进程中执行托管代码时,才需要加载CLR。一个Windows进程只可以加载一个版本的CLR。如果一个宿主进程调用了CorBindToRuntimeEx函数多次,那么每次都会返回同一个ICLRRuntimeHost指针。

        一旦CLR加载到Windows的进程,就永远不会被卸载,要想卸载进程中的CLR,只能终止进程,导致Windows清理该进程使用的所有资源。

       应用程序域(AppDomain)

         应用程序域允许第三方没有经过信任的代码在已存在的进程中运行,并且能够保证应用程序的数据结构、代码以及安全上下文不被利用或者不会遭遇安全风险。

         当CLR COM服务器开始初始化时,它就会创建一个应用程序域。一个应用程序域是一组程序集的一个容器。CLR初始化时创建的第一个应用程序域成为默认应用程序(default AppDomain),该应用程序域只有在进程终止时才会销毁。

        宿主可以指示CLR创建额外的应用程序域。应用程序域的全部目的就是提供隔离性。有以下几个方面:

        一个应用程序域的代码创建的对象不能被另一个应用程序域中的代码直接访问。windows系统的一个主要特征就是将每个应用程序都转换为自己的进程地址控件。该特征确保一个应用程序的代码不能访问另一个应用程序使用的代码或数据。

          当某个应用程序域中的代码创建了一个对象时,该对象被这个应用程序域所拥有。该对象的生存期不会超过该应用程序域的生存期。一个应用程序域中的代码只有通过使用按引用封送处理语义或者按值封送处理语义才可以访问另一个应用程序域中的对象。

         应用程序域可以被卸载。

          CLR不支持单个程序集从应用程序域中卸载。但是CLR可以卸载一个应用程序域,从而卸载其中包含的程序集。

         应用程序域可以单独实施安全策略。

          当一个应用程序域被创建时,它被设置一个许可权限,从而确定在运行时在该应用程序域中的程序集的最大访问权限。这就允许宿主在加载代码时确保这些代码不会被破坏或者读取宿主本身所用的重要的数据结构。

         应用程序域可以单独实施配置策略。

          应用程序与被创建时,它可以关联一组配置。这些设置主要影响CLR对应用程序域加载程序集的方式。

     

          上图为一个单独的Windows进程(来自CLR via C#),该进程中运行着一个CLR COM服务器。该CLR中有两个应用程序域(AppDomain)。每个应用程序域都有自己的加载器堆。如System.dll被两个AppDomain使用,那么这两个AppDomain中都会有该类型的一个对象,类型对象的内存不互相共享。 不对类型对象或者本地代码的内存进行共享看上去是不经济的。但是AppDomain的目的就是为了提供这种隔离性。另外,还有一些特殊的程序集如MSCorLib.dll,它需要被所有的应用程序域共享,那么他就以一种对应用程序域保持中立的方式被加载,由CLR维护一个特殊的加载器堆。这样的程序机永远不会被卸载,回收他们的唯一方式就是终止Windows进程。

         卸载一个应用程序域可以导致CLR卸载应用程序域中的所有程序集,并且释放应用程序域的加载器堆。可以调用AppDomain的Unload方法实现。

         跨应用程序域访问对象时有三种方式:按引用封送处理语义、按值封送处理语义、不进行封送处理。

    线程与应用程序域的关系

          在windows中,线程通常在进程的上下文中创建,而且线程的生存期与进程的生存期相同,但是线程与应用程序域没有一对一的关系。应用程序域时CLR的特征,Windows对应用程序域一无所知。因为多个应用程序域可以位于一个Windows进程中,所以一个线程可以执行一个应用程序域中的代码,然后又执行另一个应用程序域中的代码。从CLR的角度看,线程每次只能执行一个应用程序域中的代码。线程可以通过Thead的静态方法GetDomain来请求CLR当前正在那个应用程序域中执行。线程还可以查询AppDomain的CurrentDomain来获得同样的信息。

     

     

  • 相关阅读:
    Event bubbling
    input/change event practice
    Form event
    Event_Object
    DOM_this keyword
    Random color generator exercise
    DOM_events_addEventListener
    Spring值SpEL
    Spring之使用外部属性文件
    Spring之Bean的作用域
  • 原文地址:https://www.cnblogs.com/jyz/p/1290521.html
Copyright © 2011-2022 走看看