• System.AppDomain类详解(一)


      AppDomain是CLR(Common Language Runtime:公共语言运行库),它可以加载Assembly、创建对象以及执行程序。

      AppDomain是CLR实现代码隔离的基本机制。

      每一个AppDomain可以单独运行、停止;每个AppDomain都有自己默认的异常处理;一个AppDomain的运行失败不会影响到其他AppDomain的运行。

      CLR在被CLR Host(windows shell or InternetExplorer or SQL Server)加载后,会创建一个默认的AppDomain,程序的入口点(main方法)就是在这个默认的AppDomain中执行。

      1、AppDomain与进程比较:

        AppDomain被创建是在进程中,一个进程中可以有多个AppDomain,但一个AppDomain只能属于一个进程。

      2、AppDomain与线程比较:

        与线程,Appdomain是个静态概念,知识限定了对象的边界;线程是个动态的概念,它可以运行在不同的AppDomain中。一个AppDomain内可以创建多个线程,但是不能限定这些线程只能在本AppDomain内执行代码。

        CLR中的System.Threading.Thread对象其实是个soft thread,它并不能被操作系统识别;操作系统能识别的是hard thread。一个soft thread只属于一个ppDomain,穿越AppDomain的是hard thread。当hard thread访问到某个AppDomain时,一个AppDomain就会产生一个soft thread。

        hard thread有thread local storage(TLS),这个存储区被CLR用来存储hard thread当前对应的AppDomain引用以及soft thread引用。当一个hard thread穿越到另外一个AppDomain时,TLS中的这些引用也会改变。

      3、AppDomain与Assembly的比较:

        Assembly是.net程序的基本部署单元,它可以为CLR提供识别类型的元数据等等。Assembly不能单独执行,必须被加载到AppDomain中,然后由AppDomain创建程序集中的对象。一个Assembly可以被多个AppDomain加载,一个AppDomain可以加载多个Assembly。每个AppDomain引用到某个类型的时候需要把相应的assembly在各自的AppDomain中初始化。因此,每个AppDomain会单独保持一个类的静态变量。

      4、AppDomain与对象的比较:

        任何对象只能属于一个AppDomain,AppDomain用来隔离对象,不同AppDomain之间的对象必须通过Proxy(reference type)或者Clone(value type)通信。

        引用类型需要继承System.MarshalByRefObject才能被Marshal/UnMarshal(Proxy)。
        值类型需要设置Serializable属性才能被Marshal/UnMarshal(Clone)。

      5、AppDomain与Assembly Code    

        AppDomain和程序集的源代码是什么关系呢?每个程序集的代码会分别装载到各个AppDomain中?
        首先我们要把程序集分3类
        1.mscorlib,这是每个.net程序都要引用到的程序集。
        2.GAC,这个是强命名的公用程序集,可以被所有的.net程序引用。
        3.Assembly not in GAC,这是普通的assembly,可以不是强命名,不放到GAC中。
          启动CLR,进入entry point时可以设置LoaderOptimization属性:
          [LoaderOptimization(LoaderOptimization.MultiDomain]
          static void Main()
          {...}
        LoaderOptimization属性可以设置三个不同的枚举值,来设置针对前面说的三种程序集的代码存放以及访问方式。
        LoaderOptimization Enumeration/Attribute
    ValueExpected Domains in ProcessEach Domain Expected to Run ...Code for MSCORLIBCode for Assemblies in GACCode for Assemblies not in GAC
    SingleDomain One N/A Per-process Per-domain Per-domain
    MultiDomain Many Same Program Per-process Per-process Per-process
    MultiDomainHost Many Different Programs Per-process Per-process Per-domain
        1.SingleDomain,由于只启动一个AppDomain,那么code就被直接装载到了AppDomain中,访问静态变量更快捷。
        2.MultiDomain,所有的Assembly代码是进程级别的,因此所有的AppDomain只访问一份代码。这大大减少了程序占用的内存,但是由于程序集的静态变量仍然在各个AppDomain中,因此代码访问静态变量需要先得到AppDomain的引用再进行转换,速度会受到影响。
        3.MultiDomainHost,只有GAC代码是共享的,非GAC的Assembly依然会加载到被使用的AppDomain中,这样提高静态变量的访问速度,当然也增加程序占用内存。 
        不管是哪种方式,mscorlib始终是process级别的,即只有一份mscorlib代码在内存中。
     
      详细参考:http://www.cnblogs.com/foman/archive/2009/10/18/1585655.html
  • 相关阅读:
    Android导包导致java.lang.NoClassDefFoundError
    canvas
    [java]OutOfMemoryError 原因及解决办法
    [转]加速Android Studio/Gradle构建
    本地Tomcat配置ssl 实现https访问
    机器学习中的无监督学习
    SQL 创建数据库、表以及索引
    海马玩模拟器共享文件夹导入导出图文教程
    Java-SDK-图像识别实现身份证照片获取信息
    Java中的平方
  • 原文地址:https://www.cnblogs.com/wmcoder/p/5170889.html
Copyright © 2020-2023  润新知