.Net Framework CLR 之 托管执行过程
CLR作为.Net Framework的核心组件之一,承载了极其重要的基础工作,为.Net托管代码的执行提供的良好的支撑。
-
性能得到了改进。
-
能够轻松使用用其他语言开发的组件。
-
类库提供的可扩展类型。
-
语言功能,如面向对象的编程的继承、接口和重载。
-
允许创建多线程的可缩放应用程序的显式自由线程处理支持。
-
结构化异常处理支持。
-
自定义特性支持。
-
垃圾回收。
-
使用委托取代函数指针,从而增强了类型安全和安全性。(讨厌指针同学们的福音呐:P)
托管执行过程
代码(C#,VB,J#,F#)->MSIL->Native code->运行
-
代码:开发人员写的符合 CLS的程序代码,可以是C#,VB,J#,F#等
-
MSIL(Microsoft Intermediate Language):实现多语言支持的关键,同时产生元数据(Compiling translates your source code into MSIL and generates the required metadata. )
-
Native code:俺理解就是汇编语言了。(At execution time, a just-in-time (JIT) compiler translates the MSIL into native code. During this compilation, code must pass a verification process that examines the MSIL and metadata to find out whether the code can be determined to be type safe. )
-
.Net Framework提供两种方式进行MSIL到Native code的转换:
-
JIT:在应用程序运行时,JIT 编译可以在加载和执行程序集内容的过程中根据需要将 MSIL 转换为本机代码。 由于公共语言运行时为所支持的每种 CPU 体系结构都提供了一个 JIT 编译器,因此开发人员可以生成一组可在具有不同的计算机体系结构的不同计算机进行 JIT 编译和运行的 MSIL 程序集。 但是,如果托管代码调用特定于平台的本机 API 或特定于平台的类库,则将只能在该操作系统上运行。
JIT 编译考虑了在执行过程中某些代码可能永远不会被调用的可能性。 它不是耗费时间和内存将 PE 文件中的所有 MSIL 都转换为本机代码,而是在执行期间根据需要转换 MSIL 并将生成的本机代码存储在内存中,以供该进程上下文中的后续调用访问。 在加载并初始化类型时,加载程序将创建存根 (stub) 并将其附加到该类型的每个方法中。 当首次调用某个方法时,存根 (stub) 会将控制权交给 JIT 编译器,后者会将该方法的 MSIL 转换为本机代码,并修改存根 (stub) 以使其直接指向生成的本机代码。 这样,对 JIT 编译的方法的后续调用将直接转到该本机代码。
-
NGen.exe:由于 JIT 编译器会在调用程序集中定义的单个方法时将该程序集的 MSIL 转换为本机代码,因而必定会对运行时的性能产生不利影响。 在大多数情况下,这种性能降低是可以接受的。 更为重要的是,由 JIT 编译器生成的代码会绑定到触发编译的进程上。 它无法在多个进程之间进行共享。 为了能在多个应用程序调用或共享一组程序集的多个进程之间共享生成的代码,公共语言运行时支持一种提前编译模式。 此提前编译模式使用Ngen.exe(本机映像生成器) 将 MSIL 程序集转换为本机代码,其作用与 JIT 编译器极为相似。 但是,Ngen.exe 的操作与 JIT 编译器的操作有三点不同:
-
它在应用程序运行之前而不是在应用程序运行过程中执行从 MSIL 到本机代码的转换。
-
它一次编译一个整个程序集,而不是一次编译一个方法。
-
它将本机映像缓存中生成的代码以文件的形式持久保存在磁盘上。
-
-
-
代码验证:
在编译为本机代码的过程中,MSIL 代码必须通过验证过程,除非管理员已经建立了允许代码跳过验证的安全策略。 验证过程检查 MSIL 和元数据以确定代码是否是类型安全的,这意味着它仅访问已授权访问的内存位置。 类型安全帮助将对象彼此隔离,因而可以保护它们免遭无意或恶意的破坏。 它还提供了对代码可以可靠地强制安全限制的保证。
运行时使用下列条件来验证代码是否为类型安全:
-
对类型的引用与被引用的类型严格兼容。
-
在对象上只调用正确定义的操作。
-
标识与声称的要求一致。
验证过程中检查 MSIL 代码,尝试确认该代码只能通过正确定义的类型访问内存位置和调用方法。 例如,代码不允许以超出内存范围的方式来访问对象。 另外,验证过程检查代码以确定 MSIL 是否已正确生成,这是因为不正确的 MSIL 会导致违反类型安全规则。 验证过程通过正确定义的类型安全代码集,并且它只通过类型安全的代码。 然而,由于验证过程存在一些限制,某些类型安全代码可能无法通过验证,而某些语言在设计上并不产生可验证的类型安全代码。 如果安全策略要求提供类型安全代码,而该代码不能通过验证,则在运行该代码时将引发异常。
-
-
-
运行代码:The common language runtime provides the infrastructure that enables execution to take place and services that can be used during execution.