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

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


当前回答

术语解释器是一个遗留术语,可以追溯到早期的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上运行的机器

永久链接

首先,你应该明白,编程或计算机科学一般不是数学,我们经常使用的大多数术语都没有严格的定义。

现在回答你的问题:

什么是解释器(计算机科学)

它按最小的可执行单元翻译源代码,然后执行该单元。

什么是虚拟机

对于JVM来说,虚拟机是一个包含解释器、类加载器、垃圾收集器、线程调度器、JIT编译器和许多其他东西的软件。

正如你所看到的,解释器是JVM的一部分,整个JVM不能被称为解释器,因为它包含许多其他组件。

为什么在谈论python时要用“解释器”这个词

在Java中,编译部分是显式的。 另一方面,Python的编译和解释过程不像Java那样明确,从最终用户的角度来看,解释是用于执行Python程序的唯一机制

A virtual machine is a virtual computing environment with a specific set of atomic well defined instructions that are supported independent of any specific language and it is generally thought of as a sandbox unto itself. The VM is analogous to an instruction set of a specific CPU and tends to work at a more fundamental level with very basic building blocks of such instructions (or byte codes) that are independent of the next. An instruction executes deterministically based only on the current state of the virtual machine and does not depend on information elsewhere in the instruction stream at that point in time.

另一方面,解释器更复杂,因为它是为解析特定语言和特定语法的某些语法流而定制的,这些语法必须在周围标记的上下文中进行解码。您不能单独地查看每个字节甚至每一行,然后确切地知道下一步该做什么。语言中的令牌不能像相对于VM的指令(字节码)那样孤立地获取。

Java编译器将Java语言转换为字节码流,与C编译器将C语言程序转换为汇编代码没有什么不同。另一方面,解释器并不真正将程序转换为任何定义良好的中间形式,它只是将程序操作作为解释源代码的过程。

VM和解释器区别的另一个测试是你是否认为它是独立于语言的。我们所知道的Java虚拟机并不是Java特有的。您可以使用其他语言制作编译器,生成可以在JVM上运行的字节代码。另一方面,我不认为我们真的会考虑将Python以外的其他语言“编译”为Python以供Python解释器解释。

Because of the sophistication of the interpretation process, this can be a relatively slow process....specifically parsing and identifying the language tokens, etc. and understanding the context of the source to be able to undertake the execution process within the interpreter. To help accelerate such interpreted languages, this is where we can define intermediate forms of pre-parsed, pre-tokenized source code that is more readily directly interpreted. This sort of binary form is still interpreted at execution time, it is just starting from a much less human readable form to improve performance. However, the logic executing that form is not a virtual machine, because those codes still can't be taken in isolation - the context of the surrounding tokens still matter, they are just now in a different more computer efficient form.

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

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

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