Java 什么是虚拟机?为什么动态语言需要虚拟机?
例如,Python和Java有VM,而C和Haskell没有。(如果我错了,请纠正我)Java 什么是虚拟机?为什么动态语言需要虚拟机?,java,python,c,haskell,vm-implementation,Java,Python,C,Haskell,Vm Implementation,例如,Python和Java有VM,而C和Haskell没有。(如果我错了,请纠正我) 想想这条线两边都有哪些语言,我找不到原因。Java在很多方面都是静态的,而Haskell提供了很多动态特性。这与静态与动态无关 相反,它是关于独立于底层硬件平台(“一次构建,到处运行”-理论上…) 事实上,这也与语言无关。可以编写一个C编译器,为JVM生成字节码。人们可以编写一个生成x86机器代码的Java编译器。没有“需要”,这些语言中的任何一种都提供了直接发出机器代码的编译器,以在给定的体系结构中实现其语
想想这条线两边都有哪些语言,我找不到原因。Java在很多方面都是静态的,而Haskell提供了很多动态特性。这与静态与动态无关 相反,它是关于独立于底层硬件平台(“一次构建,到处运行”-理论上…) 事实上,这也与语言无关。可以编写一个C编译器,为JVM生成字节码。人们可以编写一个生成x86机器代码的Java编译器。没有“需要”,这些语言中的任何一种都提供了直接发出机器代码的编译器,以在给定的体系结构中实现其语言的语义
虚拟机的概念是将所有不同硬件和软件制造商之间的架构差异抽象出来,这样开发人员就可以编写一台机器。Java和python的编译方式可以保持平台独立性。这甚至适用于C。优点是虚拟机能够以相对较低的开销将这种主要是强类型的字节码转换为非常好的特定于平台的代码。由于Java旨在“构建一次,在任何地方运行”,因此JVM已经创建。来自以下维基百科条目: “虚拟机(VM)是一台机器(即计算机)的软件实现,它可以像物理机器一样执行程序。” 从理论上讲,虚拟机最大的资产是代码的可移植性——“写一次,在任何地方运行” 最著名的虚拟机示例可能是,最初设计用于运行Java代码,但现在也越来越多地用于Clojure和Scala等语言 没有任何特定于动态语言的东西意味着它们需要一个VM。然而,他们确实需要一个虚拟机,它可以构建在VM上。VM(虚拟机)实际上是语言设计者的一个工具,可以避免编写语言实现时的一些复杂性 基本上是虚拟计算机的规格说明,以及所述计算机的每个部件将如何相互作用。您可以在本规范中编写一些假设,这些假设可以由实际语言使用,也可以不由实际语言使用 在本规范中,通常定义处理器的工作方式、内存的工作方式、可能存在的读写障碍等,以及与之交互的更简单的汇编语言 最终语言通常是从您正在编写的文本文件翻译(编译)成为该机器编写的表示形式 这有一些好处:
- 您将语言与 特定硬件架构
- 通常允许你控制什么 发生
- 不同的人可以移植到不同的体系结构
- 您有更多信息可以优化代码
- 等等
还有一个很酷的因素:看,我做了一台虚拟机:) 虚拟机基本上是一个解释器,它解释一种更接近机器代码的语言。当真实机器解释真实机器代码时,虚拟机解释一个虚构的机器代码。一些虚拟机解释实际计算机的机器代码——这些被称为模拟器 为简单的汇编语言编写解释器比为完整的高级语言编写解释器更容易。此外,许多高级代码构造通常只是一些基本原则的语法糖衣。因此,编写一个将所有这些复杂概念翻译成简单VM语言的编译器就更容易了,因此我们不必编写复杂的解释器,只需编写一个简单的解释器(VM)。这样你就有更多的时间来优化虚拟机 这就是现在大多数语言(不能编译成真正的机器代码)的基本实现方式
解释器(VM)和编译器可以是单独的程序(如
java
和javac
),也可以是一个程序(如Ruby或Python)。想象您创建了一种编程语言:您找到了语言语义并开发了一种很好的语法
然而,文本表示是不够的:在执行程序时必须一次又一次地解析文本效率很低,因此添加内存中的二进制表示是很自然的。再加上一个定制的内存管理器,你就基本上有了一个虚拟机
现在,为了获得更多的信息,可以开发一种字节码格式来序列化内存中的表示和一个运行时加载程序,或者,如果您想使用脚本语言,可以开发一个eval()
函数
在大结局中,添加一个JIT。让我们暂时忘记VMs(我保证,我们将回到下面的内容),从这个重要事实开始: C没有垃圾收集。 对于提供垃圾收集的语言,必须有某种类型的“运行时”来执行垃圾收集 这就是为什么Python、Java和Haskell需要一个“运行时”,而C(不需要)可以直接编译为本机代码 请注意,Python优化器将Python代码编译为机器代码,但是,许多机器代码由对C-Python运行时函数的调用组成,例如
PyImport\u AddModule
,PyImport\u getmoduledit
,等等
Haskell/GHC与psyco编译的Python类似Int
s是作为简单的机器指令添加的,但是更复杂的东西分配对象等,调用运行时
还有什么
C没有“例外”
如果我们向C添加异常,我们生成的机器代码将需要为每个函数和每个函数调用做一些事情
如果我们再加上“闭包”
def has_no_letters(text):
return text.upper() == text.lower()
{ 'func_name': 'has_no_letters',
'num_args': 1,
'kwargs': [],
'codez': [
('get_attr', 'tmp_a', 'arg_0', 'upper'), # tmp_a = arg_0.upper
('func_call', 'tmp_b', 'tmp_a', []), # tmp_b = tmp_a() # tmp_b = arg_0.upper()
('get_attr', 'tmp_c', 'arg_0', 'lower'),
('func_call', 'tmp_d', 'tmp_c', []),
('get_global', 'tmp_e', '=='),
('func_call', 'tmp_f', 'tmp_e', ['tmp_b', 'tmp_d']),
('return', 'tmp_f'),
]
}