IL是基于栈的。这意味着它的所有指令都要将操作数压入(push)一个执行栈,并从栈弹出(pop)结果。由于IL没有提供操作寄存器的指令,所以人们可以很容易地创建新的语言和编译器,生成面向CLR的代码。

  IL指令还是“无类型”(typeless)的。例如,IL提供了一个add指令,它的作用是将压入栈的最后两个操作数加在一起。add指令不分32位和64位版本。add指令执行时,它判断栈中的操作数的类型,并执行恰当的操作。

  我个人认为,IL最大的优势并不在于它对底层CPU的抽象。IL提供的最大的优势在于应用程序的健壮性和安全性。将IL编译成本地CPU指令时,CLR会执行一个名为验证(verification)的过程。这个过程会检查高级IL代码,确定代码所做的一切都是安全的。例如,验证会核实调用的每个方法都有正确数量的参数,传给每个方法的每个参数都具有正确的类型,每个方法的返回值都得到了正确的使用,每个方法都有一个返回语句,等等。在托管模块的元数据中,包含了要有验证过程中使用的所有方法和类型信息。

  在Windows中,每个进程都有它自己的虚拟内存空间,这是因为不能简单地信任一个应用程序的代码。一个应用程序完全可能读写一个无效的内存地址(而且令人遗憾的是,这种情况时有发生)。将每个Windows进程都放到一个独立的地址空间,将获得健壮性与稳定性;一个进程无法干扰另一个进程。

  然而,通过验证托管代码,可确保代码不会不正确地访问内存,不会干扰到另一个应用程序的代码。这样一来,就可以放心地将多个托管应用程序放到一个Windows虚拟地址空间中运行。

  由于Windows进程需要使用大量操作系统资源,所以进程数量太多,会损害性能并制约可用的资源。在一个操作系统进程中运行多个应用程序,可减少进程数,从而增强性能,减少需要的资源,健壮性也没有丝毫下降。这是托管代码相较于非托管代码的另一个优势。

  事实上,CLR确实提供了在一个操作系统进程中执行多个托管应用程序的能力。每个托管的应用程序都在一个AppDomain中执行。默认情况下,每个托管的EXE文件都在它自己的独立地址空间中运行,这个地址空间只有一个AppDomain。然而,CLR的宿主进程(比如IIS或者Microsoft SQL Server)可决定在单个操作系统进程中运行多个AppDomain。第22章“CLR寄宿和AppDomain”会详细讨论AppDomain。

 

  返回目录 


  这里有必要强调一下健壮性和可靠性的区别,两者对应的英文单词分别是robustness和reliability。健壮性主要描述一个系统对于参数变化的不敏感性,而可靠性主要描述一个系统的正确性,也就是在你固定提供一个参数时,它应该产生稳定的、能预测的输出。例如一个程序,它的设计目标是获取一个参数并输出一个值。假如它能正确完成这个设计目标,就说它是可靠的。但在这个程序执行完毕后,假如没有正确释放内存,或者说系统没有自动帮它释放占用的资源,就认为这个程序及其“运行时”不具备健壮性。

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-01-20
  • 2022-12-23
  • 2022-02-23
  • 2021-12-25
  • 2021-11-26
  • 2021-11-24
猜你喜欢
  • 2022-03-03
  • 2021-09-08
  • 2022-03-10
  • 2021-11-30
  • 2021-12-29
  • 2021-08-08
  • 2021-09-29
相关资源
相似解决方案