|
|
1
174
在本文中,“虚拟机”指的是进程虚拟机,而不是进程虚拟机 只是一个提供通用编程环境的程序——一个程序 可以编程。 Java有一个解释器和一个虚拟机,Python有一个虚拟机 机器和翻译。“虚拟机”是一个更具挑战性的概念 Java中的通用术语“解释器”在Python中是一个更常见的术语 这与两种语言之间的主要区别有关:静态类型 primitive data types --建议的内存中存储大小的类型 数据。Java虚拟机非常简单。它要求程序员 Java字节码的信息,不仅由 Java虚拟机,但即使是 compiled into machine instructions Python虚拟机更为复杂,因为它承担着 中涉及的每个变量或数据结构的基本数据类型 活动Python将程序员从原始数据的角度解放出来 相对简洁的动态类型语言语法非常适合 交互界面。建立一个互动的系统没有任何技术障碍 这将是乏味的,所以它只是没有这样做。 在Java世界中,虚拟机因为运行程序而抢先一步 用一种可以编译成机器指令的语言编写, 相对来说,是程序。这是由于存在原始数据 其本身的类别: 可移植解释静态类型语言
可移植解释汇编语言 Java和Python中都使用术语“字节码”,但并非所有字节码都是 生而平等。字节码只是中间语言的通用术语 由编译器/解释器使用。甚至像gcc这样的C编译器也使用 intermediate language (or several) 完成工作。Java字节码包含 在这方面,Python(以及Bash、Perl、Ruby等)虚拟机确实是 不同的字节码格式:
以现实世界为例:LLVM与Java虚拟机atoms一起工作 因为所有的东西最终都会分解成亚原子粒子(真粒子) 机器操作),Python虚拟机具有最复杂的任务。 静态类型语言的Intepreter/编译器没有相同的功能 动态类型语言的解释器/编译器的负担。 静态类型语言的程序员必须填补这一空缺,为此 回报就是表现。然而,正如所有不确定函数一样 静态类型的。两个语系之间的性能差异 因此,在Python将其名称更改为HAL9000时,应该会保持平稳。 动态语言(如Python)的虚拟机实现了一些理想的 逻辑机器,不一定与任何真实的 机器指令,它执行内置例程。在Python中,整数是 一个Python对象,附带了一组属性和方法。在里面 在Java中,int是指定的位数,通常为32。这不是一个真正的问题 公平比较。Python整数应该与Java整数进行比较 整数类。Java的“int”原语数据类型无法与 原语,Python字节码也是如此。 因为Java变量是显式类型的,所以可以合理地预期 差不多 Jython 表演将与 cPython . 另一方面,一个用Python实现的Java虚拟机 过得更好。他们不是设计来这样做的。它们是为 “脚本”,即动态语言中的编程。 在虚拟机中发生的每一个操作最终都必须命中真实的硬件。虚拟机包含预编译例程,这些例程足够通用,可以执行任何逻辑操作组合。虚拟机可能不会发出新的机器指令,但它肯定会以任意复杂的顺序反复执行自己的例程。Java虚拟机、Python虚拟机和所有其他通用虚拟机在某种意义上是相同的,它们可以被诱使执行任何您可以想象的逻辑,但是它们在承担什么任务以及留给程序员什么任务方面是不同的。 Psyco for Python不是一个完整的Python虚拟机,而是一个及时的虚拟机 在其认为合适的点劫持常规Python虚拟机的编译器 可以编译几行代码——主要是它认为原语的循环 即使值随时间变化,某些变量的类型也将保持不变 每次迭代。在这种情况下,它可以放弃某些类型 完全相信类型不会改变。 这个故事的寓意是,原始数据类型信息实际上是 最后,从整体上考虑这个问题:执行Python程序 通过在Java平台上运行的Java实现的Python解释器/虚拟机 在qemu虚拟机中运行的LLVM中实现的解释器/虚拟机 在iPhone上运行的机器。 |
|
|
2
143
另一方面,解释器更复杂,因为它被定制为解析特定语言和特定语法的某些语法流,这些语法流必须在周围标记的上下文中解码。您不能孤立地查看每个字节甚至每一行,并确切地知道下一步要做什么。语言中的标记不能像相对于VM的指令(字节码)那样单独使用。 Java编译器将Java语言转换为字节码流,与C编译器将C语言程序转换为汇编代码没有什么不同。另一方面,解释器并不真正将程序转换成任何定义良好的中间形式,它只是将程序操作作为解释源代码的过程。
由于解释过程的复杂性,这可能是一个相对缓慢的过程……特别是解析和识别语言标记等,并理解源代码的上下文,以便能够在解释程序内执行过程。为了帮助加速这种解释语言,我们可以在这里定义更容易直接解释的预解析、预标记化源代码的中间形式。这种二进制形式仍然是在执行时解释的,它只是从人类可读性差得多的形式开始,以提高性能。然而,执行该表单的逻辑不是一个虚拟机,因为这些代码仍然不能单独使用——周围令牌的上下文仍然很重要,它们只是处于一种不同的更高效的计算机形式中。 |
|
|
3
61
在Java中,必须显式编译成字节码,然后在VM上只运行字节码,而不是源代码。 尽管Python在幕后使用虚拟机,但从用户的角度来看,大多数情况下都可以忽略这一细节。 |
|
4
17
,将源代码转换为一些有效的中间表示(代码),并立即执行。 ,显式执行由作为解释器系统一部分的编译器生成的存储的预编译代码。 虚拟机的一个非常重要的特性是,内部运行的软件仅限于虚拟机提供的资源。确切地说,它无法脱离其虚拟世界。想想远程代码的安全执行,Java小程序。 pyc
有关更多信息,请参阅维基百科条目: Interpreter 和 Virtual Machine here . 在这里你可以找到 Comparison of application virtual machines . 它有助于理解编译器、解释器和虚拟机之间的区别。 |
|
|
5
12
|
|
6
12
为什么是Java虚拟机,而不是Python解释器? “让我们试着回到编译理论领域,作为讨论的起点。 程序编译的典型过程包括以下步骤:
好啊现在让我们来定义术语。 文本 . 在这种情况下,程序以 源代码 解释器由程序文本提供,通常是以动态方式(逐语句或逐行)提供。对于每个输入语句,解释器构建其AST,并在更改程序的“状态”时立即对其进行计算。这是脚本语言演示的典型行为。例如,考虑BASH、Windows CMD等概念,Python也采用这种方式。 如果我们在解释器中生成与中间机器无关的二进制字节码步骤上替换基于AST的执行步骤,我们将把整个程序执行过程分为两个独立的阶段:编译和执行。在这种情况下,以前的解释器将变成字节码编译器,它将把程序从 变成一些 二进制的 虚拟机 ,它实际上解释了字节码。因此,虚拟机也被称为 字节码解释器 . 但是把你的注意力放在这里!一个经典的口译员是一个 文本解释器 二进制解释器 ! 这是Java和C所采用的方法。 编译程序 . 经典编译器将程序源代码转换为 直接执行 在目标处理器上,无需任何附加中介(无任何类型的解释器,即文本解释器或二进制解释器)。 现在让我们回到原来的问题,考虑java vypython。 最初设计为具有尽可能少的实现依赖项。它的设计基于“一次编写,随时随地运行”(WORA)的原则。要落实,, JAVA 最初设计为一种编程语言,可编译成独立于机器的语言 二进制字节码 无需重新编译。你可以考虑 JAVA 比如WORA公司 C++ . 事实上 JAVA C++ 而不是像这样的脚本语言 python C++ , 被设计成 二进制字节码 然后在 虽然 C++ 设计为以机器代码编译,然后由目标处理器直接执行。 最初设计为一种脚本编程语言,解释脚本(以 文本 python 要求 口译译员 文本 . 因此,历史上,, 开发者倾向于谈论 (因为最初, 已经作为一包 JAVA 字节码编译器及其应用 -- 虚拟机 ),及 python 开发者倾向于谈论 python 口译员(因为最初 python 文本解释器 它执行程序 文本 无需任何编译或转换为任何形式的二进制代码)。 为什么是Java虚拟机,而不是Python解释器? ,因为这两种语言的实现似乎都包含虚拟机。
因此,我们可以得出下一个结论。Java虚拟机但Python解释器是因为:
因此,Java和Python都有虚拟机,它们都是二进制字节码解释器,这可能会导致混淆,例如“ 为什么是Java虚拟机,而不是Python解释器? |
|
|
7
11
它们之间没有真正的区别,人们只是遵循创造者选择的惯例。 |
|
|
8
3
不要忘记Python有可用于x86的JIT编译器,这进一步混淆了这个问题。(见psyco)。 只有在讨论VM的性能问题时,对“解释语言”进行更严格的解释才有用,例如,与Python相比,Ruby被认为(是否?)较慢,因为它是一种解释语言,与Python不同——换句话说,上下文就是一切。 |
|
|
9
3
蟒蛇罐头 解释代码而不将其编译为字节码。 Java不能 (来自文件)。
在java中,每个文件
不得不
然而,造成这种差异的真正原因是,从一开始,java就将自己标榜为“可移植的、可执行的字节码”,而python则将自己标榜为带有REPL的动态解释语言。名字粘在一起! |
|
|
10
1
我认为两者之间的界限是模糊的,人们大多围绕“解释器”一词的含义以及该语言与“解释器…编译器”频谱两侧的距离而争论。然而,没有一家公司的利润是100%。我认为编写Java或Python实现是很容易的,这些实现具有任何价值。 目前,Java和Python都有虚拟机和字节码,尽管一个按具体的值大小(如32位整数)操作,而另一个则必须确定每个调用的大小,在我看来,这并没有定义术语之间的边界。 Python没有正式定义字节码,它只存在于内存中的说法也不能说服我,因为我计划开发只识别Python字节码的设备,编译部分将在浏览器JS机器中完成。 性能只是关于具体的实现。我们不需要知道对象的大小就可以使用它,最后,在大多数情况下,我们使用的是结构,而不是基本类型。通过重用现有对象,可以优化PythonVM,从而消除每次在表达式计算期间创建新对象的需要。一旦完成,计算两个整数之和就不会有全局性能差异,这正是Java的亮点所在。 这两者之间没有致命的区别,只有一些与最终用户无关的实现细微差别和缺乏优化,可能到了她开始注意到性能滞后的时候,但这仍然是实现问题,而不是架构问题。 |
|
|
11
0
首先,你应该明白,编程或计算机科学通常不是数学,我们对我们经常使用的大多数术语都没有严格的定义。 现在谈谈你的问题:
什么是虚拟机 对于JVM,虚拟机是一个软件,它包含解释器、类装入器、垃圾收集器、线程调度器、JIT编译器和许多其他东西。
对于java,编译部分是显式的。 另一方面,python的编译和解释过程不像java那样明确,从最终用户的角度来看,解释是执行python程序的唯一机制 |
|
|
12
0
不,它们并不都解释字节码。
Java编译成字节码。 |
|
|
13
0
对于提到python不需要生成字节码的帖子,我不确定这是真的。Python中的所有可调用项似乎都必须具有
|
|
|
14
0
首先,CPython只是一个普通的、基于堆栈的字节码解释器。您将Python操作码输入其中,CPython中的软件堆栈机器将评估您的代码,就像普通解释器一样。 Java热点运行时是不同的。首先也是最重要的,Java有3个即时编译器,C1、C2和一个尚未使用的实验性编译器。但这不是主要原因。JVM中的解释器是一种非常特殊的解释器,称为模板解释器。JVM中的模板解释器包含一个巨大的arraylist,而不是像CPython(实际上几乎所有其他解释器都这样)那样直接在一个巨大的操作码开关case语句中执行字节码。里面有什么?字节码和本机CPU指令的键值对!arraylist在启动时是空的,并且充满了字节码映射,这些字节码指向要在应用程序启动之前直接在硬件上运行的本机语言,这意味着JVM中的“解释器”实际上根本不是解释器——它实际上是一个折扣编译器!当Java字节码运行时,“解释器”只是将输入字节码直接映射到本机机器语言,并直接执行本机映射,而不是在软件中实现。我不太清楚JVM为什么会这样,但我怀疑它可以很容易地与JIT编译代码一起无缝地执行“解释”代码,并提高速度/性能。如果您在没有JIT的情况下将JVM与CPython或大多数其他解释器进行比较,它可能仍然会领先于他们,因为它的巧妙设计,据我所知,以前没有其他语言使用过。 |
|
|
user29759326 · 如何返回递归函数中的最后一个值? 1 年前 |
|
|
malife89 · 将java中的字符串读取为正确的日期格式 1 年前 |
|
|
Tim · 在java中,有没有更快的方法将字节数组写入文件? 1 年前 |
|
|
rudraraj · java中未声明最终变量 1 年前 |
|
|
Bala Ji · 以下BFS的实施效率如何? 1 年前 |