20110311.NET面试指南
时间:2011-03-12 来源:[email protected]
CLR 技术和COM 技术的比较
COM 的全称是组件对象模型(Common Object Mode) COM 定义了所有组件之间的交互和组件接口的规范。读者可以把COM理解为一种编程模型和平台技术。不同于传统的DLL, COM技术实现了接口分离。每个标准的COM组件都会包含一个接口定义文件: IDL 文件。而COM 中所有的接口都继承自!Unknown接口。对于类型, COM把其定义在一个类型库文件: TLB 文件中。这样,一个最基本的接口协议就形成了。
COM 技术确实有效地分离了接口和实现部分, 提出了例如封装、多态等概念, 很多大型系统和第三方供应商大量地采用COM技术。但COM技术也有很多天生的弊端,比较严重的是:
• COM 没有定义如何描述组件之间的依赖关系, 也不能控制版本
• COM 组件的扩展性很差
对于第一个弊端, COM没有定义如何描述组件间的依赖关系,并且由于其严格的二进制约定,同一组件的不同版本很难相互替换。而COM组件相较于其他框架规范,可扩展性也比较差。另
外, COM组件晦涩难懂,加大了程序员的上手成本。基于COM的种种缺陷,微软公司提出了CLR框架。
CLR 同样定义了组件之间交互的规范, 同时, CLR 严格定义了组件的依赖关系以及组件的自身特性。读者可能己经猜到了,这些描述就是组件的元数据。相比COM, CLR 另外一个改进是所
有的类型定义是逻辑上的,而并不严格定义内存结构。所有实际地址/偏移量都在中间代码被加载编译后动态生成,这样CLR就更容易控制组件的版本。
什么是程序集和应用程序域
程序集( Assembly )是一个或多个模块和资源文件的集合。当一个程序集被打包形成时,它不仅会包含所有的原始文件内容,也会添加一个程序集清单,该清单包含了程序集的版本号、语言、发布者、导入类型等信息。有趣的是,程序集清单可以被添加到程序集中的某个文件之上,编译器也可以为程序集清单单独创建一个文件。
(1)程序集支持多编程语言开发,就是一个程序集可以包含由不同编程语言定义和实现的模块。在程序集被编译形成时,所有这些类型已经被编译成中间代码,而不再带有原来编程语言的
特性。
(2) 程序集允许逻辑分布和物理分布分离。这样虽然同属于一个逻辑程序集, 各种类型和资源仍然可以分布在不同的物理文件里。这太大地提高了系统部署的灵活性。例如程序员可以把某个程序集分成四个文件,分别包含基本类型定义、基本HELP文档、可选类型定义和可选HELP文档。这样在部署该系统时,可以让用户选择需要的功能,并且按照用户的选择从服务器下载必要的文件来组成程序集。
应用程序域是CLR中提供代码运行范围、错误隔离和安全设置隔离的逻辑单元,功能类似于操作系统的进程。一个或多个应用程序域在一个操作系统的进程中运行。应用程序域的创建和销毁所需的开销,相对于操作系统进程较小。但和操作系统进程一样,应用程序域之间的数据共享相当困难。
JiT 是如何工作的?
JiT 的全称是实时编译(Just-In-Time ),
在编译IL代码时, .NET 提供了两种可选方式:
·利用JIT引擎进行实时编译
·在组件部署时就生成机器代码形式的缓存,以供CLR调用先来看C LR加载的顺序,当CLR需要执行某个方法时,首先会检测本地缓存,井且确定本地的缓存是最新的版本。如果缓存的版本不是最新的, CLR 将忽略缓存的机器代码而去寻找最新版本的中间代码。另外,如果CLR没有发现任何缓存代码,也会去寻找适合的中间代码并且用实时编译(lIT)的方式来编译中间代码。
在实时编译的过程中,盯引擎会查找一个包含该类型所有方法存根的数据结构,对于未编译成机器代码的方法,存根会包含一个调用lIT的简单命令,当该方法的实时编译结束后,存根的命令会被替换成-条简单的Jmp指令,使得代码跳转到该方法的机器代码位置。
lIT引擎在编译中间代码之前,会寻找方法的本机机器代码缓存并且判断其是否可用,如果可用则直接加载,如果不可用, lIT引擎会查找类型中的方法存根,找到该中间代码井且进行编译。