Java“虚拟机”与 Python“解释器”用语?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/441824/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 14:40:11  来源:igfitidea点击:

Java "Virtual Machine" vs. Python "Interpreter" parlance?

javapythonjvm

提问by twils

It seems rare to read of a Python "virtual machine" while in Java "virtual machine" is used all the time.

在 Java 中一直使用“虚拟机”时,似乎很少看到 Python“虚拟机”。

Both interpret byte codes; why call one a virtual machine and the other an interpreter?

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

采纳答案by Tall Jeff

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 类似于特定 CPU 的指令集,并且倾向于在更基础的级别上工作,这些指令(或字节代码)的非常基本的构建块独立于下一个。一条指令仅根据虚拟机的当前状态确定性地执行,不依赖于该时间点指令流中其他地方的信息。

An interpreter on the other hand is more sophisticated in that it is tailored to parse a stream of some syntax that is of a specific language and of a specific grammer that must be decoded in the context of the surrounding tokens. You can't look at each byte or even each line in isolation and know exactly what to do next. The tokens in the language can't be taken in isolation like they can relative to the instructions (byte codes) of a VM.

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

A Java compiler converts Java language into a byte-code stream no different than a C compiler converts C Language programs into assembly code. An interpreter on the other hand doesn't really convert the program into any well defined intermediate form, it just takes the program actions as a matter of the process of interpreting the source.

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

Another test of the difference between a VM and an interpreter is whether you think of it as being language independent. What we know as the Java VM is not really Java specific. You could make a compiler from other languages that result in byte codes that can be run on the JVM. On the other hand, I don't think we would really think of "compiling" some other language other than Python into Python for interpretation by the Python interpreter.

VM 和解释器之间差异的另一个测试是您是否认为它是独立于语言的。我们所知道的 Java VM 并不是真正特定于 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.

由于解释过程的复杂性,这可能是一个相对较慢的过程……特别是解析和识别语言标记等,并了解源的上下文,以便能够在解释器内进行执行过程。为了帮助加速这种解释型语言,我们可以在这里定义更容易直接解释的预解析、预标记化源代码的中间形式。这种二进制形式仍然在执行时被解释,它只是从人类可读性低得多的形式开始以提高性能。然而,执行该表单的逻辑不是虚拟机,因为这些代码仍然不能孤立地使用——周围令牌的上下文仍然很重要,它们只是现在处于一种不同的、更高效的计算机形式。

回答by Cody Brocious

There's no real difference between them, people just follow the conventions the creators have chosen.

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

回答by Mr Fooz

Probably one reason for the different terminology is that one normally thinks of feeding the python interpreter raw human-readable source code and not worrying about bytecode and all that.

使用不同术语的一个原因可能是人们通常认为将原始的人类可读源代码提供给 python 解释器,而不用担心字节码之类的。

In Java, you have to explicitly compile to bytecode and then run just the bytecode, not source code on the VM.

在 Java 中,您必须显式编译为字节码,然后只运行字节码,而不是在 VM 上运行源代码。

Even though Python uses a virtual machine under the covers, from a user's perspective, one can ignore this detail most of the time.

尽管 Python 在幕后使用了虚拟机,但从用户的角度来看,大多数时候人们可以忽略这一细节。

回答by Daniel Naab

The term interpreter is a legacy term dating back to earlier shell scripting languages. As "scripting languages" have evolved into full featured languages and their corresponding platforms have become more sophisticated and sandboxed, the distinction between a virtual machine and an interpreter (in the Python sense), is very small or non-existent.

术语解释器是一个可以追溯到早期 shell 脚本语言的遗留术语。随着“脚本语言”发展成为功能齐全的语言,并且它们相应的平台变得更加复杂和沙盒化,虚拟机和解释器(在 Python 意义上)之间的区别非常小或不存在。

The Python interpreter still functions in the same way as a shell script, in the sense that it can be executed without a separate compile step. Beyond that, the differences between Python's interpreter (or Perl or Ruby's) and Java's virtual machine are mostly implementation details. (One could argue that Java is more fully sandboxed than Python, but both ultimately provide access to the underlying architecture via a native C interface.)

Python 解释器仍然以与 shell 脚本相同的方式运行,因为它可以在没有单独编译步骤的情况下执行。除此之外,Python 的解释器(或 Perl 或 Ruby 的)和 Java 的虚拟机之间的差异主要在于实现细节。(有人可能会争辩说,Java 比 Python 更完全沙盒化,但两者最终都通过本机 C 接口提供对底层架构的访问。)

回答by Arafangion

Don't forget that Python has JIT compilers available for x86, further confusing the issue. (See psyco).

不要忘记 Python 有适用于 x86 的 JIT 编译器,这进一步混淆了这个问题。(见心理咨询)。

A more strict interpretation of an 'interpreted language' only becomes useful when discussing performance issues of the VM, for example, compared with Python, Ruby was (is?) considered to be slower because it is an interpreted language, unlike Python - in other words, context is everything.

只有在讨论 VM 的性能问题时,对“解释性语言”的更严格解释才变得有用,例如,与 Python 相比,Ruby 被(是?)被认为更慢,因为它是一种解释性语言,与 Python 不同 - 在其他方面话,语境就是一切。

回答by Adeel Ansari

Interpreter, translates source code into some efficient intermediate representation (code) and immediately executes this.

Interpreter,将源代码翻译成一些有效的中间表示(代码)并立即执行。

Virtual Machine, explicitly executes stored pre-compiled code built by a compiler which is part of the interpreter system.

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

A very important characteristic of a virtual machine is that the software running inside, is limited to the resources provided by the virtual machine. Precisely, it cannot break out of its virtual world. Think of secure execution of remote code, Java Applets.

虚拟机的一个非常重要的特性是,里面运行的软件,受限于虚拟机提供的资源。准确地说,它无法脱离虚拟世界。想想远程代码的安全执行,Java Applet。

In case of python, if we are keeping pycfiles, as mentioned in the comment of this post, then the mechanism would become more like a VM, and this bytecode executes faster -- it would still be interpreted but from a much computer friendlier form. If we look at this as a whole, PVM is a last step of Python Interpreter.

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

The bottomline is, when refer Python Interpreter, it means we are referring it as a whole, and when we say PVM, that means we are just talking about a part of Python Interpreter, a runtime-environment. Similar to that of Java, we refer different parts differentyl, JRE, JVM, JDK, etc.

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

For more, Wikipedia Entry: Interpreter, and Virtual Machine. Yet another one here. Here you can find the Comparison of application virtual machines. It helps in understanding the difference between, Compilers, Interpreters, and VMs.

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

回答by Poor Yorick

In this post, "virtual machine" refers to process virtual machines, not to system virtual machines like Qemu or Virtualbox. A process virtual machine is simply a program which provides a general programming environment -- a program which can be programmed.

在这篇文章中,“虚拟机”指的是进程虚拟机,而不是像 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 有解释器和虚拟机,Python 有虚拟机和解释器。“虚拟机”在 Java 中是一个更常见的术语,而“解释器”在 Python 中是一个更常见的术语,这与两种语言之间的主要区别有很大关系:静态类型 (Java) 与动态类型 (Python)。在这种情况下,“类型”是指 原始数据类型——暗示数据在内存中存储大小的类型。Java 虚拟机很容易。它要求程序员指定每个变量的原始数据类型。这为 Java 字节码提供了足够的信息,不仅可以被 Java 虚拟机解释和执行,甚至可以编译成机器指令. Python 虚拟机更复杂,因为它承担了在执行每个操作之前暂停的附加任务,以确定操作中涉及的每个变量或数据结构的原始数据类型。Python 将程序员从原始数据类型的思维中解放出来,并允许在更高层次上表达操作。这种自由的代价是性能。“解释器”是 Python 的首选术语,因为它必须暂停以检查数据类型,而且动态类型语言相对简洁的语法非常适合交互式界面。构建交互式 Java 界面没有技术障碍,但是尝试以交互方式编写任何静态类型的代码会很乏味,所以它不是那样做的。

In the Java world, the virtual machine steals the show because it runs programs written in a language which can actually be compiled into machine instructions, and the result is speed and resource efficiency. Java bytecode can be executed by the Java virtual machine with performance approaching that of compiled programs, relatively speaking. This is due to the presence of primitive data type information in the bytecode. The Java virtual machine puts Java in a category of its own:

在 Java 世界中,虚拟机抢占先机,因为它运行的程序是用一种实际上可以编译成机器指令的语言编写的,结果是速度和资源效率。Java字节码可以由Java虚拟机执行,相对来说性能接近编译程序。这是由于字节码中存在原始数据类型信息。Java 虚拟机将 Java 放在自己的一个类别中:

portable interpreted statically-typed language

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

The next closest thing is LLVM, but LLVM operates at a different level:

下一个最接近的是 LLVM,但 LLVM 在不同的级别上运行:

portable interpreted assembly language

可移植解释汇编语言

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:

术语“字节码”在 Java 和 Python 中都有使用,但并非所有字节码都是平等的。字节码只是编译器/解释器使用的中间语言的通用术语。甚至像 gcc 这样的 C 编译器也使用一种(或几种)中间语言来完成工作。Java 字节码包含有关原始数据类型的信息,而 Python 字节码不包含。在这方面,Python(以及 Bash、Perl、Ruby 等)虚拟机确实从根本上比 Java 虚拟机慢,或者更确切地说,它只是有更多的工作要做。考虑不同字节码格式中包含哪些信息是有用的:

  • llvm:cpu registers
  • Java:primitive data types
  • Python:user-defined types
  • llvm:cpu 寄存器
  • Java:原始数据类型
  • Python:用户定义的类型

To draw a real-world analogy: LLVM works with atoms, the Java virtual machine works with molecules, and The Python virtual machine works with materials. Since everything must eventually decompose into subatomic particles (real machine operations), the Python virtual machine has the most complex task.

打个真实世界的类比: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.

静态类型语言的解释器/编译器与动态类型语言的解释器/编译器不同。静态类型语言的程序员必须填补空缺,其回报是性能。然而,正如所有非确定性函数都是秘密确定的,所有动态类型语言也是秘密静态类型的。因此,当 Python 将其名称更改为 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.

Python 等动态语言的虚拟机实现了一些理想化的逻辑机器,不一定与任何真实的物理硬件非常接近。相比之下,Java 虚拟机在功能上更类似于经典的 C 编译器,不同之处在于它执行内置例程而不是发出机器指令。在 Python 中,整数是一个 Python 对象,它附加了一堆属性和方法。在 Java 中,int 是指定的位数,通常为 32。这不是真正的公平比较。Python 整数确实应该与 Java Integer 类进行比较。Java 的“int”原始数据类型无法与 Python 语言中的任何内容相比,因为 Python 语言只是缺少这层原始数据,Python 字节码也是如此。

Because Java variables are explicitly typed, one can reasonably expect something like Jythonperformance to be in the same ballpark as cPython. On the other hand, a Java virtual machine implemented in Python is almost guaranteed to be slower than mud. And don't expect Ruby, Perl, etc., to fare any better. They weren't designed to do that. They were designed for "scripting", which is what programming in a dynamic language is called.

由于 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.

在虚拟机中发生的每一个操作最终都必须运行到真实的硬件上。虚拟机包含预编译的例程,这些例程足够通用以执行任何逻辑操作组合。虚拟机可能不会发出新的机器指令,但它肯定会以任意复杂的顺序一遍又一遍地执行自己的例程。Java 虚拟机、Python 虚拟机和所有其他通用虚拟机在某种意义上是平等的,它们可以被诱使执行您能想到的任何逻辑,但它们在执行哪些任务方面有所不同承担,以及他们留给程序员的任务。

Psyco for Python is not a full Python virtual machine, but a just-in-time compiler that hiHymans 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.

Psyco for Python 不是一个完整的 Python 虚拟机,而是一个即时编译器,它在它认为可以编译几行代码的点上劫持常规的 Python 虚拟机——主要是在它认为某些原始类型的地方循环即使值随着每次迭代而变化,变量也将保持不变。在这种情况下,它可以放弃一些常规虚拟机的连续类型确定。但是,您必须小心一点,以免将字体从 Psyco 脚下拉出。然而,如果 Pysco 不完全确信类型不会改变,它通常知道只回退到常规虚拟机。

The moral of the story is that primitive data type information is really helpful to a compiler/virtual machine.

这个故事的寓意是原始数据类型信息对编译器/虚拟机真的很有帮助。

Finally, to put it all in perspective consider this: a Python program executed by a Python interpreter/virtual machine implemented in Java running on a Java interpreter/virtual machine implemented in LLVM running in a qemu virtual machine running on an iPhone.

最后,从正确的角度来看,请考虑以下问题:一个 Python 程序由在 Java 中实现的 Python 解释器/虚拟机执行,该程序在运行在 iPhone 上运行的 qemu 虚拟机中的 LLVM 中实现的 Java 解释器/虚拟机上运行。

permalink

永久链接

回答by mightyWOZ

First of all you should understand that programming or computer science in general is not mathematics and we don't have rigorous definitions for most of the terms we use often.

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

now to your question :

现在回答你的问题:

what is an Interpreter(in computer science)

什么是口译员(在计算机科学中)

It translates source code by smallest executable unit and then executes that unit.

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

what is a virtual machine

什么是虚拟机

in case of JVM the virtual machine is a software which contains an Interpreter, class loaders, garbage collector, thread scheduler , JIT compiler and many other things.

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

as you can see interpreter is a part or JVM and whole JVM can not be called an interpreter because it contains many other components.

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

why use word "Interpreter" when talking about python

为什么在谈论python时使用“解释器”一词

with java the compilation part is explicit. python on the other hand is not explicit as java about its compilation and interpretation process, from end user's perspective interpretation is the only mechanism used to execute python programs

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

回答by Michael Tamillow

No, they don't both interpret byte code.

不,它们不都解释字节码。

Python only interprets bytecode if you are running with pypy. Otherwise it is compiled into C and interpreted at that level.

如果您使用 pypy,Python 只会解释字节码。否则,它会被编译成 C 并在该级别进行解释。

Java compiles to bytecode.

Java 编译为字节码。

回答by ZarathustrA

To provide a deep answer to the question "Why Java Virtual Machine, but Python interpreter?" let's try to go back to the field of compilation theory as to the starting point of the discussion.

为了深入回答“为什么是 Java 虚拟机,但是 Python 解释器?”这个问题让我们试着回到编译理论领域作为讨论的起点。

The typical process of program compilation includes next steps:

程序编译的典型过程包括以下步骤:

  1. Lexical analysis. Splits program text into meaningful "words" called tokens(as part of the process all comments, spaces, new-lines etc. are removed, because they do not affect program behavior). The result is an ordered stream of tokens.
  2. Syntax analysis. Builds the so-called Abstract Syntax Tree (AST)from the stream of tokens. AST establish relations between tokens and, as a consequence, defines an order of evaluation of the program.
  3. Semantic analysis. Verifies semantical correctness of the AST using information about types and a set of semantical rules of the programming language. (For example, a = b + cis a correct statement from the syntaxis point of view, but completely incorrect from the semantic point of view if awas declared as a constant object)
  4. Intermediate code generation. Serializes AST into the linearly ordered stream of machine independent "primitive" operations. In fact, code generator traverses AST and logs the order of evaluation steps. As a result, from the tree-like representation of the program, we achieve much more simple list-like representation in which order of program evaluation is preserved.
  5. Machine code generation. The program in the form of machine independent "primitive" bytecode is translated into machine code of particular processor architecture.
  1. 词法分析。将程序文本拆分为称为标记的有意义的“单词” (作为过程的一部分,所有注释、空格、换行符等都将被删除,因为它们不会影响程序行为)。结果是一个有序的令牌流。
  2. 语法分析。从令牌流构建所谓的抽象语法树 (AST)。AST 在令牌之间建立关系,并因此定义程序的评估顺序。
  3. 语义分析。使用有关类型的信息和编程语言的一组语义规则来验证 AST 的语义正确性。(例如,a = b + c从语法的角度来看是正确的语句,但如果a被声明为常量对象,从语义的角度来看则完全不正确)
  4. 中间代码生成。将 AST 序列化为与机器无关的“原始”操作的线性排序流。事实上,代码生成器遍历 AST 并记录评估步骤的顺序。结果,从程序的树状表示中,我们实现了更简单的类列表表示,其中保留了程序评估的顺序。
  5. 机器码生成。机器无关“原始”字节码形式的程序被翻译成特定处理器架构的机器码。

Ok. Lets now define the terms.

好的。现在让我们定义这些术语。

Interpreter, in the classical meaning of that word, assumes execution based on the program evaluation based on AST produced directly from the program text. In that case, a program is distributed in the form of source codeand the interpreter is fed by program text, frequently in a dynamic way (statement-by-statement or line-by-line). For each input statement, interpreter builds its AST and immediately evaluates it changing the "state" of the program. This is a typical behavior demonstrated by scripting languages. Consider for example Bash, Windows CMD etc. Conceptually, Python takes this way too.

在该词的经典含义中,解释器假定执行基于直接从程序文本生成的基于 AST 的程序评估。在这种情况下,程序以源代码的形式分发,解释器由程序文本提供,通常以动态方式(逐句或逐行)。对于每个输入语句,解释器构建它的 AST 并立即评估它改变程序的“状态”。这是脚本语言展示的典型行为。考虑例如 Bash、Windows CMD 等。从概念上讲,Python 也采用这种方式。

If we replace the AST-based execution step on the generation of intermediate machine-independent binary bytecode step in the interpreter we will split the entire process of program execution into two separate phases: compilation and execution. In that case what previously was an interpreter will become a bytecode compiler, which will transform the program from the form of the textinto some binaryform. Then the program is distributed in that binary form, but not in the form of source code. On the user machine, that bytecode is fed into a new entity -- virtual machine, which in fact interpret that bytecode. Due to this, virtual machines are also called bytecode interpreter. But put your attention here! A classical interpreter is a text interpreter, but a virtual machine is a binary interpreter! This is an approach taken by Java and C#.

如果我们在解释器中将基于 AST 的执行步骤替换为与机器无关的中间二进制字节码步骤,我们会将程序执行的整个过程分为两个独立的阶段:编译和执行。在那种情况下,以前的解释器将变成字节码编译器,它将程序从文本形式转换为某种二进制形式。然后程序以二进制形式分发,而不是以源代码的形式分发。在用户机器上,该字节码被送入一个新实体——虚拟机,它实际上解释了该字节码。因此,虚拟机也被称为字节码解释器。但是把你的注意力放在这里!经典解释器是文本解释器,但虚拟机是二进制解释器!这是 Java 和 C# 采用的一种方法。

Finally, if we add the machine code generation to the bytecode compiler we achieve in result what we call a classical compiler. A classical compiler converts the program source code into the machine codeof a particular processor. That machine code then can be directly executedon the target processor without any additional mediation (without any kind of interpreter neither text interpreter nor binary interpreter).

最后,如果我们将机器码生成添加到字节码编译器中,我们将实现我们所说的经典编译器。经典编译器将程序源代码转换为特定处理器的机器代码。该机器代码然后可以直接在目标处理器上执行而无需任何额外的中介(没有任何类型的解释器,文本解释器或二进制解释器)。

Lets now go back to the original question and consider Java vs Python.

现在让我们回到最初的问题并考虑 Java 与 Python。

Javawas initially designed to have as few implementation dependencies as possible. Its design is based on the principle "write once, run anywhere" (WORA). To implement it, Javawas initially designed as a programming language that compiles into machine-independent binary bytecode, which then can be executed on all platforms that support Javawithout the need for its recompilation. You can think about Javalike about WORA-based C++. Actually, Javais closer to C++than to the scripting languages like Python. But in contrast to C++, Javawas designed to be compiled into binary bytecodewhich then is executed in the environment of the virtual machine, while C++was designed to be compiled in machine code and then directly executed by the target processor.

Java最初设计为具有尽可能少的实现依赖性。它的设计基于“一次编写,随处运行”(WORA)的原则。为了实现它,Java最初被设计为一种编程语言,可以编译成与机器无关的二进制字节码,然后可以在所有支持Java 的平台上执行,而无需重新编译。您可以将Java视为基于 WORA 的C++。实际上,Java更接近C++,而不是像Python这样的脚本语言。但与C++ 相比Java被设计成二进制字节码,然后在虚拟机环境中执行,而C++被设计成机器码,然后直接由目标处理器执行。

Pythonwas initially designed as a kind of scripting programing language which interprets scripts (programs in the form of the textwritten in accordance with the programming language rules). Due to this, Python has initially supported a dynamic interpretation of one-line commands or statements, as the Bash or Windows CMD do. For the same reason, initial implementations of Python had not any kind of bytecode compilers and virtual machines for execution of such bytecode inside, but from the start Pythonhad required interpreterwhich is capable to understand and evaluate Python program text.

Python最初被设计为一种脚本编程语言,它解释脚本(按照编程语言规则编写的文本形式的程序)。因此,Python 最初支持对单行命令或语句的动态解释,就像 Bash 或 Windows CMD 所做的那样。出于同样的原因,巨蟒的初步实现了没有任何一种字节码编译器和这样的字节码内的执行虚拟机,而是从一开始的Python有需要解释这是能够理解和评价Python程序文本

Due to this, historically, Javadevelopers tended to talk about Java Virtual Machine(because initially, Javahas come as package of Javabytecode compiler and bytecode interpreter-- JVM), and Pythondevelopers tended to talk about Pythoninterpreter (because initially Pythonhas not any virtual machine and was a kind of classical text interpreterthat executes program textdirectly without any sort of compilation or transformation into any form of binary code).

由于这个原因,在历史上,Java的开发者倾向于谈论Java虚拟机(因为最初的Java已经为包的Java字节码编译器和字节码解释器- JVM)和Python的开发者倾向于谈论的Python解释器(因为最初的Python有不是任何虚拟机,而是一种经典的文本解释器,它直接执行程序文本,无需任何形式的编译或转换为任何形式的二进制代码)。

Currently, Python also has the virtual machine under the hood and can compile and interpret Python bytecode. And that fact makes an additional investment into the confusion "Why Java Virtual Machine, but Python interpreter?", because it seems that implementations of both languages contain virtual machines. But! Even in the current moment interpretation of program text is a primary way of Python programs execution. Python implementations exploit virtual machines under the hood exclusively as an optimization technique. Interpretation of binary bytecode in the virtual machine is much more efficient than a direct interpretation of the original program text. At the same time, the presence of the virtual machine in the Python is absolutely transparent for both Python language designers and Python programs developers. The same language can be implemented in interpreters with and without the virtual machine. In the same way, the same programs can be executed in interpreters with and without the virtual machine, and that programs will demonstrate exactly the same behavior and produce equally the same output from the equal input. The only observable difference will be the speed of program execution and the amount of memory consumed by the interpreter. Thus, the virtual machine in Python is not an unavoidable part of the language design, but just an optional extension of the major Python interpreter.

目前,Python 也有引擎盖下的虚拟机,可以编译和解释 Python 字节码。而这一事实为“为什么是 Java 虚拟机,但 Python 解释器?并且该程序将展示完全相同的行为,并从相同的输入中产生相同的输出。唯一可观察到的区别是程序执行速度和解释器消耗的内存量。因此,Python 中的虚拟机并不是语言设计中不可避免的一部分,而只是主要 Python 解释器的可选扩展。

Java can be considered in a similar way. Java under the hood has a JIT compiler and can selectively compile methods of Java class into machine code of the target platform and then directly execute it. But! Java still uses bytecode interpretation as a primary way of Java program execution. Like Python implementations which exploit virtual machines under the hood exclusively as an optimization technique, the Java virtual machines use Just-In-Time compilers exclusively for optimization purposes. Similarly, just because of the fact that direct execution of the machine code at least ten times faster than the interpretation of Java bytecode. And like in the case of Python, the presence of JIT compiler under the hood of JVM is absolutely transparent for both Java language designers and Java program developers. The same Java programming language can be implemented by JVM with and without JIT compiler. And in the same way, the same programs can be executed in JVMs with and without JIT inside, and the same programs will demonstrate exactly the same behavior and produce equally the same output from the equal input on both JVMs (with and without JIT). And like in the case of Python, the only observable difference between them, will be in the speed of execution and in the amount of memory consumed by JVM. And finally, like in the case of Python, JIT in Java also is not an unavoidable part of the language design, but just an optional extension of the major JVM implementations.

可以以类似的方式考虑 Java。Java底层有一个JIT编译器,可以有选择地将Java类的方法编译成目标平台的机器码,然后直接执行。但!Java 仍然使用字节码解释作为 Java 程序执行的主要方式。就像 Python 实现在引擎盖下专门利用虚拟机作为优化技术一样,Java 虚拟机专门使用实时编译器进行优化。同样,仅仅因为直接执行机器码至少比解释 Java 字节码快十倍。和 Python 一样,JVM 引擎盖下的 JIT 编译器对于 Java 语言设计人员和 Java 程序开发人员来说都是绝对透明的。JVM 可以使用 JIT 编译器和不使用 JIT 编译器来实现相同的 Java 编程语言。以同样的方式,相同的程序可以在内部有和没有 JIT 的 JVM 中执行,并且相同的程序将展示完全相同的行为,并从两个 JVM(有和没有 JIT)上的相同输入产生同样相同的输出。和 Python 一样,它们之间唯一可观察到的区别在于执行速度和 JVM 消耗的内存量。最后,就像 Python 一样,Java 中的 JIT 也不是语言设计中不可避免的一部分,而只是主要 JVM 实现的可选扩展。并且相同的程序将展示完全相同的行为,并从两个 JVM(有和没有 JIT)上的相同输入产生同样相同的输出。和 Python 一样,它们之间唯一可观察到的区别在于执行速度和 JVM 消耗的内存量。最后,就像 Python 一样,Java 中的 JIT 也不是语言设计中不可避免的一部分,而只是主要 JVM 实现的可选扩展。并且相同的程序将展示完全相同的行为,并从两个 JVM(有和没有 JIT)上的相同输入产生同样相同的输出。和 Python 一样,它们之间唯一可观察到的区别在于执行速度和 JVM 消耗的内存量。最后,就像 Python 一样,Java 中的 JIT 也不是语言设计中不可避免的一部分,而只是主要 JVM 实现的可选扩展。

From the point of view of design and implementation of virtual machines of Java and Python, they differ significantly, while (attention!) both still stay virtual machines. JVM is an example of a low-level virtual machine with simple basic operations and high instruction dispatch cost. Python in its turn is a high-level virtual machine, for which instructions demonstrate complex behavior, and instruction dispatch cost is not so significant. Java operates with very low abstraction level. JVM operates on the small well-defined set of primitive types and has very tight correspondence (typically one to one) between bytecode instructions and native machine code instructions. In contrary, Python virtual machine operates at high abstraction level, it operates with complex data types (objects) and supports ad-hoc polymorphism, while bytecode instructions expose complex behavior, which can be represented by a series of multiple native machine code instructions. For example, Python supports unbounded range mathematics. Thus Python VM is forced to exploit long arithmetics for potentially big integers for which result of the operation can overflow the machine word. Hence, one bytecode instruction for arithmetics in Python can expose into the function call inside Python VM, while in JVM arithmetic operation will expose into simple operation expressed by one or few native machine instructions.

从 Java 和 Python 的虚拟机的设计和实现的角度来看,它们有很大的不同,而(注意!)两者都仍然是虚拟机。JVM 是低级虚拟机的一个例子,具有简单的基本操作和高指令调度成本。Python反过来是一个高级虚拟机,指令表现出复杂的行为,指令调度成本不是那么大。Java 以非常低的抽象级别运行。JVM 在定义良好的小型原始类型集上运行,并且在字节码指令和本机机器代码指令之间具有非常紧密的对应关系(通常是一对一)。相反,Python 虚拟机运行在高抽象级别,它处理复杂的数据类型(对象)并支持临时多态性,而字节码指令暴露了复杂的行为,可以用一系列多本机代码指令来表示。例如,Python 支持无界范围数学。因此,Python VM 被迫对潜在的大整数使用长算术,其运算结果可能会溢出机器字。因此,Python 中用于算术的一条字节码指令可以暴露在 Python VM 内部的函数调用中,而在 JVM 中算术运算将暴露为由一条或几条本地机器指令表示的简单操作。因此,Python VM 被迫对潜在的大整数使用长算术,其运算结果可能会溢出机器字。因此,Python 中用于算术的一条字节码指令可以暴露在 Python VM 内部的函数调用中,而在 JVM 中算术运算将暴露为由一条或几条本地机器指令表示的简单操作。因此,Python VM 被迫对潜在的大整数使用长算术,其运算结果可能会溢出机器字。因此,Python 中用于算术的一条字节码指令可以暴露在 Python VM 内部的函数调用中,而在 JVM 中算术运算将暴露为由一条或几条本地机器指令表示的简单操作。

As a result, we can draw the next conclusions. Java Virtual Machine but Python interpreter is because:

因此,我们可以得出下一个结论。Java 虚拟机但 Python 解释器是因为:

  1. The term of virtual machine assumes binary bytecode interpretation, while the term interpreter assumes program text interpretation.
  2. Historically, Java was designed and implemented for binary bytecode interpretation and Python was initially designed and implemented for program text interpretation. Thus, the term "Java Virtual Machine" is historical and well established in the Java community. And similarly, the term "Python Interpreter" is historical and well established in the Python community. Peoples tend to prolong the tradition and use the same terms that were used long before.
  3. Finally, currently, for Java, binary bytecode interpretation is a primary way of programs execution, while JIT-compilation is just an optional and transparent optimization. And for Python, currently, program text interpretation is a primary way of Python programs execution, while compilation into Python VM bytecode is just an optional and transparent optimization.
  1. 虚拟机术语假设二进制字节码解释,而解释器术语假设程序文本解释。
  2. 从历史上看,Java 是为二进制字节码解释而设计和实现的,而 Python 最初是为程序文本解释而设计和实现的。因此,术语“Java 虚拟机”在 Java 社区中具有历史意义并且已经确立。同样,术语“Python 解释器”在 Python 社区中具有历史意义并且已经确立。人们倾向于延续传统并使用很久以前使用的相同术语。
  3. 最后,目前对于 Java 来说,二进制字节码解释是程序执行的主要方式,而 JIT 编译只是一种可选的透明优化。而对于 Python 而言,目前,程序文本解释是 Python 程序执行的主要方式,而编译成 Python VM 字节码只是一种可选的透明优化。


Therefore, both Java and Python have virtual machines are binary bytecode interpreters, which can lead to confusion such as "Why Java Virtual Machine, but Python interpreter?". The key point here is that for Python, a virtual machine is not a primary or necessary means of program execution; it is just an optional extension of the classical text interpreter. On the other hand, a virtual machine is a core and unavoidable part of Java program execution ecosystem. Static or dynamic typing choice for the programming language design affects mainly the virtual machine abstraction level only, but does not dictate whether or not a virtual machine is needed. Languages using both typing systems can be designed to be compiled, interpreted, or executed within the environment of virtual machine, depending on their desired execution model.

因此,Java 和 Python 的虚拟机都是二进制字节码解释器,这会导致诸如“为什么是 Java 虚拟机,但 Python 解释器?”。这里的关键是,对于 Python 来说,虚拟机不是程序执行的主要或必要手段;它只是经典文本解释器的可选扩展。另一方面,虚拟机是核心,不可避免Java 程序执行生态系统的一部分。编程语言设计的静态或动态类型选择主要仅影响虚拟机抽象级别,但并不决定是否需要虚拟机。使用两种类型系统的语言都可以设计为可编译的、解释或在虚拟机环境中执行,这取决于它们所需的执行模型。