如果C#不是解释型语言,那为什么需要一个虚拟机(VM)?
如果C#不是解释型语言,为什么还需要虚拟机(VM)?
C#是一种编译型语言,它的代码在运行之前需要先编译成中间语言(IL)代码。而虚拟机(VM)则是用来执行这些IL代码的运行环境。那么为什么C#需要一个虚拟机呢?
首先,C#是基于CLI(Common Language Infrastructure)规范的实现,而CLI规范定义了特定的类型系统、对这些类型的操作的语义、内存模型和运行时元数据。为了提供上述所有功能,必须对生成的代码进行一些仪器化操作。一个简单的例子就是确保支持大于32位的数字,并且在每种架构上浮点运算的行为都符合规范。
此外,为了确保内存分配的正确行为、元数据的正确管理、静态初始化、泛型类型实例化等,必须在执行CLR代码的过程中进行一些额外的处理。这些都由虚拟机负责,而CPU不能直接提供这些功能。
维基百科上有这样一句话:
“CLR还提供了包括内存管理、类型安全和异常处理在内的其他服务。”
因此,虚拟机在执行C#代码时起到了关键的作用,它提供了一些必要的功能和服务,以确保代码的正确执行。虽然C#不是解释型语言,但虚拟机的存在使得C#能够在不同的平台上运行,并且提供了一些额外的功能和安全措施。
问题的出现原因是C#作为一种编译型语言,为什么还需要虚拟机(VM)?
出现这个问题的原因是因为C#语言在运行时需要依赖于.NET虚拟机(也称为公共语言运行时,CLR)。虚拟机中包含了JIT编译器,它负责将C#程序中的中间语言(IL)转换为本机机器代码。此外,虚拟机还包含了.NET类库,这是C#程序所依赖的基础库。虚拟机还包含了一些与动态链接等相关的机制,这些机制建立在Windows DLL机制之上,但.NET在这方面提供了一些超出Windows自身提供的功能,这些功能是在虚拟机中实现的。
解决这个问题的方法是使用虚拟机来提供C#程序的运行环境。虚拟机通过将IL代码转换为本机机器代码,实现了C#程序的即时编译和执行。虚拟机还提供了.NET类库,这样C#程序可以使用这些类库中提供的功能。另外,虚拟机还负责处理动态链接等相关的机制,以确保C#程序的正常运行。
总之,尽管C#是一种编译型语言,但为了提供C#程序的运行环境,我们仍然需要依赖于.NET虚拟机。虚拟机通过提供JIT编译器、.NET类库和其他相关机制,实现了C#程序的编译和执行过程。
如果C#不是解释执行的,那为什么需要虚拟机?
虚拟机(VM)是微处理器的抽象。它只是一个定义,实际上并不存在。也就是说,你不能在虚拟机上运行代码;然而,你可以为其生成IL代码。优点在于,语言编译器不需要了解不同类型的真实处理器的细节。由于不同的.NET语言(如C#或VB等)都会生成IL,它们在这个层面上是兼容的。这个特性,再加上其他约定,比如一个公共类型系统,允许你在C#程序中使用从VB代码生成的DLL。
IL代码在Windows上实时编译运行.NET应用程序,并且也可以在Mono和.NET 8开始时提前编译(参见:Native AOT deployment)。在这两种情况下,都会生成针对实际处理器的本机机器码。这个完全编译的代码在真实的微处理器上执行!
另一个方面是你需要编写的编译器的数量。如果你有n种语言,并且想要在m种处理器架构上运行它们,你需要n个语言到IL编译器和m个IL到本机代码编译器。如果没有这个中间抽象层,你需要有n × m个编译器,而这个数量可能比n + m要多得多!
"这个完全编译的代码在真实的微处理器上执行"……没错,但还会执行与IL无关的额外代码,实现虚拟机的行为(对于C#来说,这是.NET公共语言运行时)。
是的,CLR管理加载、链接JIT编译、安全性方面、内存管理等等。但我更愿意将其与操作系统进行比较,而不是与虚拟机进行比较。