Python的“虚拟机”似乎很少读到,而在Java中“虚拟机”一直被使用。

两者都解释字节码;为什么一个叫虚拟机,另一个叫解释器?


当前回答

他们之间没有真正的区别,人们只是遵循创造者选择的惯例。

其他回答

for posts that mention that python does not need to generate byte code, I'm not sure that's true. it seems that all callables in Python must have a .__code__.co_code attribute which contains the byte code. I don't see a meaningful reason to call python "not compiled" just because the compiled artifacts may not be saved; and often aren't saved by design in Python, for example all comprehension compile new bytecode for it's input, this is the reason comprehension variable scope is not consistent between compile(mode='exec, ...) and compile compile(mode='single', ...) such as between running a python script and using pdb

不要忘记Python为x86提供了JIT编译器,这进一步混淆了问题。(见psyco)。

对“解释型语言”的更严格的解释只有在讨论VM的性能问题时才有用,例如,与Python相比,Ruby被认为更慢,因为它是一种解释型语言,不像Python——换句话说,上下文就是一切。

术语解释器是一个遗留术语,可以追溯到早期的shell脚本语言。由于“脚本语言”已经演变成功能齐全的语言,它们对应的平台也变得更加复杂和沙箱化,虚拟机和解释器(在Python意义上)之间的区别非常小,甚至不存在。

Python解释器仍然以与shell脚本相同的方式运行,从某种意义上说,它可以在不需要单独的编译步骤的情况下执行。除此之外,Python解释器(或Perl或Ruby的)和Java虚拟机之间的区别主要是实现细节。(有人可能会说Java比Python更加完全沙箱化,但两者最终都通过原生C接口提供对底层架构的访问。)

在本文中,“虚拟机”指的是进程虚拟机,不是指 系统虚拟机,如Qemu或Virtualbox。进程虚拟机为 一个简单的程序,它提供了一个通用的编程环境——程序 这是可以编程的。

Java has an interpreter as well as a virtual machine, and Python has a virtual machine as well as an interpreter. The reason "virtual machine" is a more common term in Java and "interpreter" is a more common term in Python has a lot to do with the major difference between the two languages: static typing (Java) vs dynamic typing (Python). In this context, "type" refers to primitive data types -- types which suggest the in-memory storage size of the data. The Java virtual machine has it easy. It requires the programmer to specify the primitive data type of each variable. This provides sufficient information for Java bytecode not only to be interpreted and executed by the Java virtual machine, but even to be compiled into machine instructions. The Python virtual machine is more complex in the sense that it takes on the additional task of pausing before the execution of each operation to determine the primitive data types for each variable or data structure involved in the operation. Python frees the programmer from thinking in terms of primitive data types, and allows operations to be expressed at a higher level. The price of this freedom is performance. "Interpreter" is the preferred term for Python because it has to pause to inspect data types, and also because the comparatively concise syntax of dynamically-typed languages is a good fit for interactive interfaces. There's no technical barrier to building an interactive Java interface, but trying to write any statically-typed code interactively would be tedious, so it just isn't done that way.

在Java世界中,虚拟机最引人注目,因为它运行程序 用一种可以编译成机器指令的语言编写, 结果就是速度和资源效率。可以执行Java字节码 通过Java虚拟机,性能接近编译 程序,相对来说。这是由于原始数据的存在 在字节码中键入信息。Java虚拟机将Java放在 自身类别:

可移植的解释静态类型语言

仅次于LLVM的是LLVM,但LLVM在不同的级别上运行:

可移植解释汇编语言

The term "bytecode" is used in both Java and Python, but not all bytecode is created equal. bytecode is just the generic term for intermediate languages used by compilers/interpreters. Even C compilers like gcc use an intermediate language (or several) to get the job done. Java bytecode contains information about primitive data types, whereas Python bytecode does not. In this respect, the Python (and Bash,Perl,Ruby, etc.) virtual machine truly is fundamentally slower than the Java virtual machine, or rather, it simply has more work to do. It is useful to consider what information is contained in different bytecode formats:

Llvm: CPU寄存器 原始数据类型 Python:用户定义类型

做一个现实世界的类比:LLVM使用原子,即Java虚拟机 Python虚拟机处理的是材料。 因为所有东西最终都必须分解成亚原子粒子(真实的 机器操作),Python虚拟机有最复杂的任务。

Intepreters/compilers of statically-typed languages just don't have the same baggage that interpreters/compilers of dynamically-typed languages have. Programmers of statically-typed languages have to take up the slack, for which the payoff is performance. However, just as all nondeterministic functions are secretly deterministic, so are all dynamically-typed languages secretly statically-typed. Performance differences between the two language families should therefore level out around the time Python changes its name to HAL 9000.

The virtual machines of dynamic languages like Python implement some idealized logical machine, and don't necessarily correspond very closely to any real physical hardware. The Java virtual machine, in contrast, is more similar in functionality to a classical C compiler, except that instead of emitting machine instructions, it executes built-in routines. In Python, an integer is a Python object with a bunch of attributes and methods attached to it. In Java, an int is a designated number of bits, usually 32. It's not really a fair comparison. Python integers should really be compared to the Java Integer class. Java's "int" primitive data type can't be compared to anything in the Python language, because the Python language simply lacks this layer of primitives, and so does Python bytecode.

因为Java变量是显式类型的,所以可以合理地期望 比如Jython的性能在同一范围内 cPython的。另一方面,一个用Python实现的Java虚拟机 肯定比泥的速度要慢。不要指望Ruby, Perl等等, 为了更好的生活。它们的设计初衷不是这样的。它们是为 “脚本”,这是动态语言编程的称呼。

Every operation that takes place in a virtual machine eventually has to hit real hardware. Virtual machines contain pre-compiled routines which are general enough to to execute any combination of logical operations. A virtual machine may not be emitting new machine instructions, but it certainly is executing its own routines over and over in arbirtrarily complex sequences. The Java virtual machine, the Python virtual machine, and all the other general-purpose virtual machines out there are equal in the sense that they can be coaxed into performing any logic you can dream up, but they are different in terms of what tasks they take on, and what tasks they leave to the programmer.

Psyco for Python is not a full Python virtual machine, but a just-in-time compiler that hijacks the regular Python virtual machine at points it thinks it can compile a few lines of code -- mainly loops where it thinks the primitive type of some variable will remain constant even if the value is changing with each iteration. In that case, it can forego some of the incessent type determination of the regular virtual machine. You have to be a little careful, though, lest you pull the type out from under Psyco's feet. Pysco, however, usually knows to just fall back to the regular virtual machine if it isn't completely confident the type won't change.

这个故事的寓意是原始数据类型信息实际上是 有助于编译器/虚拟机。

最后,考虑以下情况:执行一个Python程序 由Python解释器/运行在Java上的Java虚拟机实现 解释器/虚拟机在LLVM中实现,运行在qemu虚拟中 在iPhone上运行的机器

永久链接

解释器,翻译源代码为一些有效的中间表示(代码),并立即执行。

虚拟机,显式地执行存储的预编译代码,由编译器构建,它是解释器系统的一部分。

虚拟机的一个非常重要的特征是,在虚拟机内部运行的软件,受限于虚拟机提供的资源。确切地说,它无法跳出它的虚拟世界。想想远程代码的安全执行,Java applet。

在python的情况下,如果我们保留pyc文件,就像这篇文章的评论中提到的,那么这个机制将变得更像一个虚拟机,并且这个字节码执行得更快——它仍然会被解释,但从一个更计算机友好的形式。如果我们从整体上看,PVM是Python解释器的最后一步。

底线是,当我们提到Python解释器时,这意味着我们将其作为一个整体来引用,而当我们说PVM时,这意味着我们只是在谈论Python解释器的一部分,一个运行时环境。类似于Java,我们引用不同的部分,JRE, JVM, JDK等。

有关更多信息,请参阅维基百科条目:解释器和虚拟机。这里还有一个。在这里您可以找到应用程序虚拟机的比较。它有助于理解编译器,解释器和vm之间的区别。