我正在阅读这个问题,以找出Java虚拟机和.NET CLR之间的差异,Benji的回答让我想知道为什么虚拟机首先是必要的.
根据我对Benji的解释的理解,虚拟机的JIT编译器将中间代码解释为在CPU上运行的实际汇编代码.它必须这样做的原因是因为CPU通常具有不同数量的寄存器,并且根据Benji的说法,"一些寄存器是特殊用途的,并且每个指令都要求其操作数在不同的寄存器中." 这是有道理的,因此需要像虚拟机这样的中间解释器,以便可以在任何CPU上运行相同的代码.
但是,如果是这种情况,那么我不明白为什么编译成机器代码的C或C++代码能够在任何计算机上运行,只要它是正确的操作系统.那么为什么我在使用Pentium的Windows机器上编译的C程序能够在我使用AMD的其他Windows机器上运行?
如果C代码可以在任何CPU上运行,那么虚拟机的目的是什么?是否可以在任何操作系统上运行相同的代码?我知道Java在几乎任何操作系统上都有VM版本但除了Windows之外还有其他操作系统的CLR吗?
或者还有其他我想念的东西?操作系统是否对其运行的汇编代码做了一些其他解释,以使其适应特定的CPU或其他东西?
我很好奇这一切是如何运作的,所以我们将非常感谢一个明确的解释.
注意:我之所以不在JVM与CLR问题中发表我的查询作为评论的原因是因为我没有足够的积分发表评论但= b.
编辑:感谢所有的好答案!所以我似乎缺少的是,虽然所有处理器都有差异,但是有一个共同的标准化,主要是X86架构,它提供了足够大的通用功能集,因此在一个X86处理器上编译的C代码将在大多数情况下工作在另一个X86处理器上.这进一步推动了虚拟机的正当性,更不用说我忘记了垃圾收集的重要性.
AMD和intel处理器使用相同的指令集和机器架构(从执行机器代码的角度来看).
C和C++编译器编译为机器代码,其头文件适用于他们所针对的操作系统.一旦编译,它们就不再以任何方式,形状或形式与它们编译的语言相关联,并且仅仅是二进制可执行文件.(有些工件可能会显示它是从哪种语言编译而来的,但这不是重点)
因此,一旦编译,它们就与机器(X86,intel和amd指令集和体系结构)和操作系统相关联.
这就是为什么它们可以运行在任何兼容的x86机器和任何兼容的操作系统(win95到winvista,对于某些软件).
但是,它们无法在OSX计算机上运行,即使它在intel处理器上运行 - 除非您运行其他仿真软件(例如parallels或带有Windows的VM),否则二进制文件不兼容.
除此之外,如果你想在ARM处理器,MIPS或PowerPC上运行它们,那么你必须运行一个完整的机器指令集模拟器,它将二进制机器代码从X86解释为你正在运行它的任何机器.
与.NET对比.
.NET虚拟机的制作好像世界上有更好的处理器 - 理解对象,内存分配和垃圾收集的处理器,以及其他高级构造.它是一个非常复杂的机器,现在无法直接在硅片中构建(具有良好的性能),但可以编写一个仿真器,允许它在任何现有的处理器上运行.
突然之间,您可以为要运行.NET的任何处理器编写一个特定于机器的仿真器,然后可以在其上运行任何.NET程序.无需担心操作系统或底层CPU架构 - 如果有.NET VM,则软件将运行.
但是,让我们再进一步 - 一旦你掌握了这种共同语言,为什么不让编译器将任何其他书面语言转换成它呢?
所以现在你可以使用C,C#,C++,Java,javascript,Basic,python,lua或任何其他语言编译器来转换已编写的代码,以便它可以在这个虚拟机上运行.
你已经将机器与语言分离了2度,并且没有太多的工作你可以让任何人编写任何代码并让它在任何机器上运行,只要存在编译器和VM来映射两个分离度.
如果您仍然想知道为什么这是一件好事,请考虑早期的DOS机器,以及微软对这个世界的真正贡献是:
Autocad必须为每个可以打印的打印机编写驱动程序.莲花1-2-3也是如此.事实上,如果您想要打印软件,则必须编写自己的驱动程序.如果有10个打印机和10个程序,则必须单独和独立地编写100个不同的基本相同的代码.
Windows 3.1尝试实现的目标(以及GEM和许多其他抽象层)使打印机制造商为其打印机编写了一个驱动程序,程序员为Windows打印机类编写了一个驱动程序.
现在有10个程序和10个打印机,只需要编写20个代码,并且由于代码的microsoft方面对每个人来说都是相同的,因此来自MS的示例意味着您几乎没有什么工作要做.
现在,一个程序并不仅限于他们选择支持的10台打印机,而是制造商为Windows提供驱动程序的所有打印机.
应用程序开发中也出现了同样的问题.由于我不使用MAC,因此我无法使用真正的应用程序.有大量的重复(我们真正需要多少世界级的文字处理器?).
Java本来是为了解决这个问题,但它有很多限制,其中一些并没有真正解决.
.NET更接近,但没有人为Windows以外的平台开发世界级的虚拟机(单声道是如此接近......但还不完全存在).
所以...这就是我们需要虚拟机的原因.因为我不想仅仅因为他们选择了与我自己不同的操作系统/机器组合,所以我不想将自己限制在较小的受众群体中.
-亚当
您假设C代码可以在任何处理器上运行是不正确的.寄存器和字节序之类的东西会使编译的C程序在一个平台上根本不起作用,而它可能在另一个平台上起作用.
但是,处理器共享有一些相似之处,例如,英特尔x86处理器和AMD处理器共享足够大的属性集,大多数代码编译的属性将在另一个上运行.但是,如果要使用特定于处理器的属性,则需要一个编译器或一组库来执行此操作.
至于为什么你想要一个虚拟机,除了它将为你处理处理器差异的声明之外,还有一个事实是虚拟机为今天用C++(未管理)编译的程序不可用的代码提供服务.
提供的最突出的服务是垃圾收集,由CLR和JVM提供.这两个虚拟机都免费为您提供此服务.他们为您管理记忆.
还提供了诸如边界检查,访问违规(尽管仍然可能,它们非常困难)之类的事情.
CLR还为您提供了一种代码安全形式.
对于许多不与虚拟机一起运行的其他语言,这些都不作为基本运行时环境的一部分提供.
您可以通过使用库来获取其中的一些,但随后会强制您使用库的模式,而在.NET和Java服务中,通过CLR和JVM提供给您的访问是一致的.