Java“虚拟机”与Python“解释器”的说法?
在Java中使用“虚拟机”时,读取Python“虚拟机”似乎很less见。 两者都解释字节码,为什么称一个虚拟机,另一个解释器?
虚拟机是一种虚拟计算环境,它具有特定的primefaces定义明确的指令集,独立于任何特定的语言而被支持,并且通常被认为是自己的沙箱。 VM类似于特定CPU的指令集,并且倾向于在更基础的层面上工作,而这些指令(或字节代码)的非常基本的构build块独立于下一个。 指令仅基于虚拟机的当前状态确定性地执行,并且不依赖于该时间点的指令stream中其他地方的信息。
另一方面,解释器更复杂,因为解释器是为parsing特定语言的某种语法stream和特定语法stream而量身定制的,该语法stream必须在周围的令牌的上下文中被解码。 你不能孤立地看每个字节甚至每一行,并确切地知道下一步该做什么。 语言中的令牌不能像虚拟机的指令(字节代码)那样隔离。
Java编译器将Java语言转换为与C编译器不同的字节码stream,将C语言程序转换为汇编代码。 另一方面,解释者并没有真正将程序转换成任何明确定义的中间forms,而只是将程序行为作为解释源的过程。
VM和解释器之间差异的另一个testing是你是否认为它是独立于语言的。 我们所知的Java VM并不是真正的Java特定的。 您可以使用其他语言的编译器生成可以在JVM上运行的字节代码。 另一方面,我不认为我们真的会想把Python以外的其他一些语言编译成Python来解释Python解释器。
由于解释过程的复杂性,这可能是一个相对缓慢的过程……特别是parsing和识别语言标记等,并理解源的上下文以便能够在解释器内执行执行过程。 为了帮助加速这种解释型语言,我们可以在这里定义更容易直接解释的中间forms的预parsing,预先标记的源代码。 这种二进制forms在执行时仍然被解释,它只是从一个更不可读的forms开始,以提高性能。 然而,执行该表单的逻辑不是虚拟机,因为这些代码仍然不能孤立地被采用 – 周围的令牌的上下文仍然是重要的,他们现在只是在一个不同的更有效的计算机forms。
在这篇文章中,“虚拟机”是指进程虚拟机,而不是像Qemu或Virtualbox这样的系统虚拟机。 一个进程虚拟机就是一个简单的程序,它提供了一个通用的编程环境 – 一个可编程的程序。
Java有一个解释器和一个虚拟机,Python有一个虚拟机和一个解释器。 “虚拟机”是Java中比较常见的术语,“解释器”是Python中比较常见的一个术语,与两种语言(静态types(Java)和dynamictypes(Python))之间的主要差异有很大关系。 在这种情况下,“types”是指原始数据types – 表示数据在内存中的存储大小的types。 Java虚拟机很容易。 它要求程序员指定每个variables的原始数据types。 这为Java字节码提供了足够的信息,不仅可以被Java虚拟机解释和执行,甚至可以被编译成机器指令 。 Python虚拟机更复杂,因为在执行每个操作之前,它会承担额外的暂停任务,以确定操作中涉及的每个variables或数据结构的原始数据types。 Python让程序员从原始数据types的angular度思考,并允许在更高层次上expression操作。 这种自由的代价就是performance。 “解释器”是Python的首选术语,因为它必须暂停检查数据types,还因为dynamictypes语言的相对简洁的语法非常适合于交互式界面。 构build交互式Java接口没有任何技术障碍,但是试图以交互方式编写任何静态types的代码将是单调乏味的,所以不会这样做。
在Java世界中,虚拟机会窃取节目,因为它运行的是用实际上可以编译成机器指令的语言编写的程序,其结果是速度和资源效率。 Java字节码可以被Java虚拟机执行,相对而言性能接近编译程序的性能。 这是由于字节码中存在原始数据types信息。 Java虚拟机将Java放入其自己的类别中:
便携式解释静态types语言
第二个最接近的是LLVM,但是LLVM在不同的层次上运行:
便携式解释汇编语言
术语“字节码”用于Java和Python,但不是所有的字节码都是相同的。 字节码只是编译器/解释器使用的中间语言的通用术语。 即使像gcc这样的C编译器也使用一种中间语言(或几种)来完成工作。 Java字节码包含关于原始数据types的信息,而Python字节码则不包含。 在这方面,Python(和Bash,Perl,Ruby等)虚拟机确实比Java虚拟机要慢得多,或者说,它只是有更多的工作要做。 考虑不同字节码格式中包含的信息是有用的:
- llvm: cpu寄存器
- Java:原始数据types
- Python:用户定义的types
为了绘制一个真实世界的类比:LLVM与primefaces协同工作,Java虚拟机与分子协同工作,Python虚拟机与材料协同工作。 由于一切都必须最终分解为次primefaces粒子(真正的机器操作),所以Python虚拟机具有最复杂的任务。
静态types语言的Intepreters /编译器没有与dynamictypes语言的解释器/编译器相同的行李。 静态types语言的程序员必须占据这个松弛的位置,而这个回报就是性能。 但是,正如所有非确定性函数都是秘密确定性的,所有dynamictypes语言都是静态types的。 这两个语言家族之间的性能差异应该在Python改名为HAL 9000的时候出现。
像Python这样的dynamic语言的虚拟机实现了一些理想化的逻辑机器,并不一定非常接近任何真实的物理硬件。 相比之下,Java虚拟机在function上与传统的C编译器更相似,不同的是它不是发出机器指令,而是执行内置的例程。 在Python中,整数是一个Python对象,它附带了一系列属性和方法。 在Java中,int是指定的位数,通常是32位。这不是一个公平的比较。 Python整数实际上应该与Java Integer类进行比较。 Java的“int”原始数据types不能与Python语言中的任何东西进行比较,因为Python语言只是缺less这一层原语,Python字节码也是如此。
因为Javavariables是明确的types化的,所以我们可以合理地期望类似Jython的性能和cPython一样 。 另一方面,用Python实现的Java虚拟机几乎可以保证比泥浆更慢。 不要指望Ruby,Perl等等更好。 他们没有devise这样做。 它们是为“脚本”而devise的,这就是所谓的dynamic语言编程。
在虚拟机中发生的每一个操作最终都要碰到真正的硬件。 虚拟机包含预编译的例程,这些例程通用于执行逻辑操作的任何组合。 虚拟机可能不会发出新的机器指令,但是它肯定会以复杂的顺序反复执行自己的例程。 Java虚拟机,Python虚拟机以及所有其他通用虚拟机在这个意义上是相同的,它们可以被哄骗执行任何您可以梦想的逻辑,但是它们在什么任务上有所不同承担,以及他们给程序员什么任务。
用于Python的Psyco不是一个完整的Python虚拟机,而是一个即时编译器,它劫持常规的Python虚拟机,它认为它可以编译几行代码 – 主要是循环,它认为某些原始types即使值每次迭代都在变化,variables也会保持不变。 在这种情况下,它可以放弃一些常规虚拟机的types确定。 但是,你必须小心一点,以免从Psyco的脚下拉出types。 然而,Pysco通常知道如果不能完全确信types不会改变,就会回退到常规虚拟机。
故事的寓意是,原始数据types信息对编译器/虚拟机真的很有帮助。
最后,为了全方位考虑这个问题:一个由Java解释器/虚拟机执行的Python程序,运行在运行在iPhone上运行的qemu虚拟机中运行的LLVM中的Java解释器/虚拟机上。
永久链接
可能一个不同的术语的一个原因是,人们通常认为喂养python解释器原始的人类可读的源代码,而不是担心字节码等等。
在Java中,您必须显式编译为字节码,然后只运行字节码,而不是VM上的源代码。
尽pipePython使用虚拟机,但从用户的angular度来看,大多数情况下都可以忽略这个细节。
解释器 ,将源代码翻译成一些有效的中间表示(代码),并立即执行此操作。
虚拟机 ,显式地执行存储的预编译的代码,该编译器是解释器系统的一部分。
虚拟机的一个非常重要的特点是运行在其中的软件仅限于虚拟机提供的资源。 确切地说,它不能摆脱它的虚拟世界。 想想远程代码Java Applet的安全执行。
在python的情况下,如果我们保留pyc文件,就像这篇文章的评论中提到的那样,那么这个机制就会变得更像虚拟机,而且这个字节码的执行速度会更快 – 它仍然会被解释,但是会从更加计算机友好的forms。 如果我们从整体来看,PVM是Python解释器的最后一步。
底线是,当提到Python解释器时,这意味着我们将它作为一个整体来引用,当我们说PVM时,这意味着我们只是谈论Python解释器(一种运行时环境)的一部分。 类似于Java,我们参考不同的部分differentyl,JRE,JVM,JDK等。
欲了解更多,维基百科条目: 解释器和虚拟机 。 还有一个在这里 。 在这里您可以find应用程序虚拟机的比较 。 它有助于理解编译器,口译员和虚拟机之间的差异。
术语解释器是一个遗留术语,可以追溯到早期的shell脚本语言。 由于“脚本语言”已经演变为全function的语言,并且其相应的平台变得更加复杂和沙盒化,虚拟机和解释器(在Python意义上)之间的区别非常小或不存在。
Python解释器的function仍然与shell脚本相同,因为它可以在没有单独的编译步骤的情况下执行。 除此之外,Python的解释器(或Perl或Ruby)与Java的虚拟机之间的差异大多是实现细节。 (人们可以争辩说Java比Python更完全的沙盒化,但是最终都是通过本地C接口提供对底层架构的访问。)
他们之间没有真正的区别,人们只是遵循创作者select的习俗。
不要忘记,Python有适用于x86的JIT编译器,进一步混淆了这个问题。 (见psyco)。
在讨论VM的性能问题时,对“解释型语言”的更严格的解释只会变得很有用,例如,与Python相比,Ruby被认为是更慢的,因为它是一种解释型语言,与Python不同 – 在其他单词,上下文就是一切。
首先,您应该明白,编程或计算机科学通常不是math,而且我们对于经常使用的大多数术语没有严格的定义。
现在你的问题:
什么是口译员 (在计算机科学)
它用最小的可执行单元翻译源代码,然后执行该单元。
什么是虚拟机
在JVM的情况下,虚拟机是一个包含解释器,类加载器,垃圾收集器,线程调度器,JIT编译器等等的软件。
正如你所看到的,解释器是JVM的一部分,整个JVM不能被称为解释器,因为它包含许多其他组件。
为什么在谈论python时使用“Interpreter”这个词呢?
用java编译的部分是显式的。 另一方面python并不像java那样显式的编译和解释过程,从最终用户的angular度来看,解释是用来执行python程序的唯一机制