《ClR via C#》chapter1 CLR的执行模式
chapter1 CLR的执行模式
1.1将源代码编译成托管模块
公共语言运行时(Common Language Runtime CLR)是一个可由多种编程语言使用的“运行时”。
只要是面向CLR的编译器,基本上Microsof的都是面向CLR的,都会直接将源代码编译成托管模块
如下图,都会变成托管模块。
一般托管模块由四个部分组成:PE32||PE32+头、CLR头、元数据、IL代码
其中元数据和IL代码是重要的
元数据中的两种表包括了源代码定义和引用的类型和成员
CLR通过编译器生成的IL代码转换成本机CUP指令
ps.元数据有很多用途(比如VS中的智能联想)
1.2将托管模块合并成程序集
程序集assembly是一个抽象的概念,是一个或多个模块的逻辑性分组,是重用、安全性以及版本控制的最小单元。这里我认为就是你所编译出来的托管模块合在一起变成了程序集,然后CLR和这些程序集打交道。
程序集相当于“组件”。
1.3加载公共语言运行时
一般Windos在一开始就已经安装了.Net Framework,CLR就在其中,应该是属于配置在操作系统上的附加的软件。
1.4执行程序集的代码
JIT(just in time)是CLR的编译器,目的就是将托管程序集中的所引用或定义的IL代码转换成本机CUP指令。第一次执行WriteLIne函数:
第二次执行WriteLine函数:
因为该方法第一次已经将该IL指令编译成本机代码了,所以直接执行该内存块中的代码。
两个C#编译器开关会影响代码优化:optimize、debug
托管代码相较于非托管代码的优势:
1、JIT编译器能判断应用程序是否运行在Inter Pentium4 CUP 上,并生成相应的本机代码来利用Pentium4支持的任何特殊指令。
2、JIT能判断一个特定的测试在它的运行的机器上是否总是失败
if(numofcpus>1)
{…
}
如果该主机只有一个cpu,则不会为上述代码生成任何指令。
3、应用程序运行时,CLR可以评估代码的执行,并将IL重新编译成本机代码。等
1.41IL和验证
IL基于栈,IL是“无类型”的,将IL代码编译成本机CPU指令时,CLR会执行一个验证的过程,该过程会检查高级IL代码,确认代码所做的一切都是安全的。
CLR提供了在一个操作系统进程中执行多个托管应用程序的能力,每个应用程序都在一个AppDomain中。
1.42不安全代码
Microsoft c#编译器默认生成安全代码,但也支持写不安全代码。
JIT编译一个不安全方法时,它会检查方法所在的程序集是否授权了、标志是否设置了,若设置了,JIT会编译这些代码,并且运行。否则JIT会抛出异常,禁止方法执行。
1.5本机代码生成器:NGen.exe
运用NGen.exe可以在应用程序安装到用户计算机上时,将IL代码编译成本机代码。提升应用程序的性能。
优点:1、提高应用程序的启动速度 2、减小应用程序的工作集。
缺点:1、没有知识产权保护 2、NGen生成的文件可能失去同步 3、较差的执行时性能。
1.6Freamwork类库
.Net Framework 包含Framework类库Frame Class Library,FCl。FCL是一组DLL程序集的统称,其中有很多类型的定义,每个类型都公开了一些功能。
1.7通用类型系统(CTS common Type system)
只要是面向CLR的代码都应该遵循CTS规范。
CTS规定一个类型可以包含多个成员。
字段、方法、属性、事件。
CTS的可视边界:
private
family(protect)
family and assembly
assembly (internal)
family or assembly (protect internal)
public
CTS还规定所有类型必须从预定义的System.Object类型继承。
1.8公共语言规范(CLS common language specification)
简单来说,要想一个语言编译出来的程序集能在另一种语言中运用,那么就要符合CLS,还有我们所有的面向CLR的语言都要遵循CTS。如图
1.9与非托管模块的互操作性
·托管代码能调用DLL中的非托管函数
·托管代码可以使用现有的COM组件(服务器)
·非托管代码可以使用托管类型(服务器)