zoukankan      html  css  js  c++  java
  • 第二十二章 CLR寄宿和AppDomain

    1. 概念解析

    CLR Hosting(CLR 宿主):初始启动.Net Application时,Windows进程的执行和初始化跟传统的Win32程序是一样的,执行的还是非托管代码,只不过由于PE文件中引入了CLR Header,OS进程加载了mscoree.dll,从而启动了CLR,CLR本身不是一个可执行程序,它需要一个进程来装载并启动它,从而接管进程并创建自身的程序运行上下文,这个过程可称之为CLR Hosting。从本质上来讲,CLR是一个COM服务器,它自身封装了一系列称之为CLR Hosting APIs的接口,以便于CLR寄宿于非托管程序,从而在非托管环境上下文中执行托管程序。比如SQL Server2005和ASP.NET都运用了此种技术使CLR寄宿于其运行环境。托管代码是如何在目标进程内执行的

    2. 托管程序与非托管程序的区别

    参考:

    对于托管的和非托管的程序集编译器都会把程序集编译成以.exe或.dll等为扩展名的文件,可见Windows加载器并没有区分是托管还是非托管的程序集.

    对于托管还是非托管程序集,他们在编译器执行编译时都会编译成一个特殊的文件格式,即PE文件(可移植可执行文件格式),操作系统加载器通过加载这样的PE文件来执行程序集的。可以这么说吧,无论是托管程序还是非托管程序他们实际上都是编译成这样的PE文件(只是有部分内容不一样而已).

    然后这个PE文件会指示如何执行托管程序集和非托管程序集,加载器首先会查找到PE头中的AddressOfEntryPoint域,这个域指示PE文件的入口点位置,在.NET程序集中是指向.text段中的CLR头--〉包含一个结构IMAGE_COR20_HEADER—>包含许多信息如托管代码应用程序的入口点,目标CLR的主版本号和从版本号,以及程序集的强名称签名等--〉Windows加载器根据这个数据结构决定加载哪个版本的CLR以及一些基本的程序集信息。在.text段中还包含了程序集的元数据表,MSIL以及非托管启动存根代码,而非托管启动存根代码包好了由Windows加载器执行役启动PE文件执行的代码

    (1)非托管程序的执行过程
    在非托管程序中,可执行里面保存的是机器代码,CPU可以直接加载并执行,当系统加载了可执行程序后,系统就将可执行文件的段基址加上偏移地址形成实际的物理地址,并直接加载到内存中运行。

    (2)托管程序的执行过程
    托管程序的可执行文件中,包含的是中间语言以及元数据,当然不能直接运行,必须启动CLR,由CLR对中间语言进行即时编译成机器代码,并加载到内存里面执行(具体过程:程序在进入入口函数前会提前跳转到MSCoree.dll中,调用它的代码来启动CLR并完成一些初始化工作)。当然,IL中的方法并不是每次被调用都会被编译一次,而是它只有在第一次调用时才进行编译,即时编译器会将方法名称以及对应的入口地址存放在映射表中,当下次调用该方法时,会直接从映射表里去而不是再编译一次。

    3. AppDomain

    AppDomain: 是一个CLR的功能,Windows对AppDomain一无所知.线程和AppDomain没有一对一的关系.

    Thread.GetDomain查询线程正在执行那个AppDomain. System.AppDomain.CurrentDomain获取同样的信息.

    CLR在我们的任何代码运行之前就创建了默认的 AppDomain,并且用可执行文件的文件名作为默认的AppDomain的友好名称.

    跨越AppDomain边界访问对象

    System.Runtime.Remoting.RemotingServices.IsTransparentProxy 返回一个布尔值,该值指示给定的对象是透明代理还是实际对象

    按引用封送: MarshalByRefObject 抽象类,允许在支持远程处理的应用程序中跨应用程序域边界访问对象.实现这个类的类型可以跨域按照引用封送.

    按值封送:如果一个对象没有实现MarshalByRefObject ,但是具有Serializabled属性,就可以序列化按值封送.

    使用不可封送的类型跨域访问,会抛出异常.

    监视AppDomain

    使用AppDomain.MonitoringIsEnabled=true获取或设置一个值,该值指示是否对当前进程启用应用程序域的 CPU 和内存监视。 一旦对进程启用了监视,则无法将其禁用。

    AppDomain FirstChanceException异常通知

    event EventHandler<System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs> FirstChanceException 当托管代码抛出异常时发生,在运行时在调用堆栈中搜索应用程序域中的异常处理程序之前.不能处理异常,也不能吞噬异常,只能接收一个通知.可以用来执行日志记录功能.

    Thread.GetDomain().FirstChanceException += Program_FirstChanceException;
            try {
                throw new Exception() { };

            } catch (Exception) {

            }

    private static void Program_FirstChanceException(object sender, FirstChanceExceptionEventArgs args)
        {这里可以收到通知

        }

  • 相关阅读:
    LeetCode120 Triangle
    LeetCode119 Pascal's Triangle II
    LeetCode118 Pascal's Triangle
    LeetCode115 Distinct Subsequences
    LeetCode114 Flatten Binary Tree to Linked List
    LeetCode113 Path Sum II
    LeetCode112 Path Sum
    LeetCode111 Minimum Depth of Binary Tree
    Windows下搭建PHP开发环境-WEB服务器
    如何发布可用于azure的镜像文件
  • 原文地址:https://www.cnblogs.com/zhangliming/p/3492174.html
Copyright © 2011-2022 走看看