我有一个关于解释器、编译器和虚拟机(VM)的问题。
现在我知道解释器和编译器之间的区别,但是虚拟机与前两者有什么不同呢?使用虚拟机相比于解释器和编译器有哪些优缺点呢?
非常感谢。
我有一个关于解释器、编译器和虚拟机(VM)的问题。
现在我知道解释器和编译器之间的区别,但是虚拟机与前两者有什么不同呢?使用虚拟机相比于解释器和编译器有哪些优缺点呢?
非常感谢。
一台虚拟机并不是编译器或解释器的替代品。我认为你在想JIT编译器,许多虚拟机都是这样实现的。
虚拟机本身就是其名称所描述的——一个不存在的机器(处理器)。例如,大多数处理器没有任何内在的方法来处理内存分配,也不具备任何类型知识。然而Java虚拟机(VM)却有一个new
指令用于分配某个类的实例。VM的设计者决定将这个概念作为语言中重要的部分赋予其自己的操作码,这是VM中的基本操作单元。
创建自己的指令集的优点通常在于弥合了长时间编译/优化时间和慢速解释器之间的差距。例如,当你编译Java类时,你不需要进行寄存器分配、内联或任何传统编译器的工作。JIT会在以后执行该操作,但只针对您运行足够次数的代码部分,并分布在程序运行期间。JVM的指令集与Java非常接近,因此初始编译很快,并且对于VM来说阅读起来简单快捷,不像Java源代码那样。
至于解释器和JIT编译器的区别,通常是围绕运行时性能与开发时间之间的权衡。JIT需要更长的开发时间,但在运行时速度更快;然而,在许多情况下,例如脚本和中小型网站,程序运行时间太短,以至于你无法真正看到使用JIT带来的任何好处。
我还应该提到像VMware这样的软件。这也是一台虚拟机,但它使用的指令集也恰好用于真实的硬件上。它与语言VM具有相同的基本概念,即假装是一台不存在的物理机器,但在实践中却不同且非常复杂。
通俗易懂版
编译器将一种语言转换为另一种语言。例如,将C#转换为IL、Java转换为字节码、C++转换为二进制机器代码。在编译阶段不进行执行。
解释器从源文件中逐行解释(执行)代码。例如PHP、Perl和其他脚本语言。
虚拟机可以指几个不同的东西,我知道其中两个:
这三者没有优劣之分,它们执行不同的任务,很难进行比较。
语言和平台没有特定的顺序,还有数百个其他示例
虽然这是一个老问题,但我认为我可以增加价值。传统上,编译器或解释器将高级语言翻译成运行在目标计算机上的机器语言。
在虚拟机(VM)出现之前,每对高级语言和目标机器语言都需要一个独特的编译器或解释器。这导致了依赖于高级语言和目标计算机机器语言每个细节的编译器和解释器。
通过将高级语言到机器语言的翻译分为两个步骤并使用两个单独的程序,我们打破了这种依赖性。
第一个程序将高级语言翻译成中间代码。在Java中,这称为字节码。第一个程序仍然被称为编译器。
第二个程序将此中间代码翻译成目标计算机的机器语言。
运行中间代码的概念系统称为虚拟机。
现在同一编译器可以用于任何存在接受编译器生成的中间代码的虚拟机的计算机。
某些语言的编译器共享同一个VM,使得来自一个语言的例程可以轻松调用共享同一VM的另一种语言的例程。
关于VM的完整解释以及创建自己的VM的指导练习可以在Noam Nisan和Shimon Schoken的书《计算系统要素》中找到。