第二十二章 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)
{这里可以收到通知}
第二十二章 CLR寄宿和AppDomain的更多相关文章
- 《Linux命令行与shell脚本编程大全》 第二十二章 学习笔记
第二十二章:使用其他shell 什么是dash shell Debian的dash shell是ash shell的直系后代,ash shell是Unix系统上原来地Bourne shell的简化版本 ...
- 第二十二章 Django会话与表单验证
第二十二章 Django会话与表单验证 第一课 模板回顾 1.基本操作 def func(req): return render(req,'index.html',{'val':[1,2,3...]} ...
- Gradle 1.12用户指南翻译——第二十二章. 标准的 Gradle 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
- “全栈2019”Java多线程第二十二章:饥饿线程(Starvation)详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第二十二章:try-with-resources语句详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java第二十二章:控制流程语句中的决策语句if-else
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- python 教程 第二十二章、 其它应用
第二十二章. 其它应用 1) Web服务 ##代码 s 000063.SZ ##开盘 o 26.60 ##最高 h 27.05 ##最低 g 26.52 ##最新 l1 26.66 ##涨跌 c ...
- 第二十二章 跳出循环-shift参数左移-函数的使用 随堂笔记
第二十二章 跳出循环-shift参数左移-函数的使用 本节所讲内容: 22.1 跳出循环 22.2 Shift参数左移指令 22.3 函数的使用 22.4 实战-自动备份mysql数据库和nginx服 ...
- 20190925 On Java8 第二十二章 枚举
第二十二章 枚举 基本 enum 特性 创建 enum 时,编译器会为你生成一个相关的类,这个类继承自 Java.lang.Enum. valueOf() 是在 Enum 中定义的 static 方法 ...
随机推荐
- XSS获取cookie
在你服务器的html目录下创建joke文件夹: 在joke文件夹中创建joke.js 和joke.php joke.js 创建img标签,将它的src属性指向另一个脚本joke.php,这里关键的一点 ...
- perl中shift 和unshift 操作
##################################################################### unshift 和shift 对一个数组的开头进行操作(数组 ...
- SetTimeOut jquery的作用
1. SetTimeOut() 1.1 SetTimeOut()语法例子 1.2 用SetTimeOut()执行Function 1.3 SetTimeOut()语法例子 1.4 设定条件使SetTi ...
- 10、WPF程序集
WPF核心程序集 PresentationCore.dll:这个程序集定义了许多构成WPF GUI层基础的类型.例如包含WPF Ink API(pc笔针输入,手写输入)的支持.几个动画基元以及几个图形 ...
- ios系统 处理内存警告
iPhone下每个app可用的内存是被限制的,如果一个app使用的内存超过20M,则系统会向该app发送Memory Warning消息.收到此消息后,app必须正确处理,否则可能出错或者出现内存泄露 ...
- 【转】java获取当前路径的几种方法
1.利用System.getProperty()函数获取当前路径: System.out.println(System.getProperty("user.dir"));//use ...
- Notes of the scrum meeting(10/28)
meeting time:4:00~6:00p.m.,October 28th,2013 meeting place:雕刻时光 attendees: 顾育豪 ...
- Swift和OC,是编译型语言、解释性语言、运行时语言
首先需要明确的一点是,什么是编译型语言和解释性语言 编译型语言,就是在其执行过程中需要先将其经过编译成机器码来给计算机识别的,其执行效率就会比较高这个是显而易见的,常见比如:C.C++ 而解释型语言, ...
- Array.Copy
var bt = new byte[] { 0x03, 0x00, 0x01, 0xD9, 0x23 }; var result = new byte[] { 0x01, 0x00, 0x03, 0x ...
- Careercup - Google面试题 - 4807591515389952
2014-05-06 00:45 题目链接 原题: What would happen if you have only one server for a web cache (a web brows ...