IL和验证

IL是基于栈的, 这意味着所有的指令都将操作数放到执行栈上, 然后从栈弹出结果. 因为IL没有提供操作寄存器的指令, 编译器开发者很容易产生IL代码, 他们不需要考虑管理寄存器, 只需要很少的IL指令(因为不存在寄存器操作).

IL指令也是无类型的, 例如, IL提供一个add指令, 它对栈上的最后两个操作数进行加法操作, 没有单独的32位和64位版本的add指令, 当执行add指令时, 它要确定栈上操作数的类型, 然后执行适当的操作.

IL最大的好处不是从潜在的CPU抽象出来, 而是IL为应用程序提供了鲁棒性和安全性. 当编译IL为native CPU指令时, CLR执行一个被称为验证(verification)的过程, 这个验证要检查被调用的每个方法以及参数的正确数目, 检查每个传入的参数的类型, 检查每个方法的返回值是否被正确地使用, 检查每个方法是否具有返回声明, 等等. 托管模块的metadata包括了验证过程需要的所有方法和类型信息.

在Windows中, 每个进程有它自己的虚地址空间, 单独的地址空间是必要的, 这是因为你不能完全相信每个应用程序的代码, 完全有可能(不幸的是非常常见)应用程序会读取或者写入一个非法的内存地址. 通过将每个Windows进程放到一个单独的地址空间中, 你会获得很好的鲁棒性和稳定性, 每个进程不会影响到其他进程.

然而, 通过验证托管代码, 代码不会不适当地访问非法内存, 不会影响其他应用程序的代码. 这意味着你能在一个Windows虚地址空间中运行多个托管的应用程序.

因为Windows进程需要很多操作系统资源, 使用过多的资源会损害性能和限制可用的资源. 通过在单OS进程中运行多个应用程序可以减少进程的数量, 需要较少的资源, 这和每个应用程序在自己的进程中运行一样鲁棒, 这是托管代码的另一个好处.

实际上, CLR提供了在一个OS进程中执行多个托管应用程序的能力, 每个托管的应用程序被称为应用程序域(AppDomain). 默认情况下, 每个托管的EXE文件运行在他自己单独的地址空间中, 只有一个AppDomain. 然而, CLR的宿主进程(例如IIS服务器和SQL Server 2005)可以决定在一个OS进程中运行多个AppDomain。

你可能感兴趣的:(验证)