JVM是编译器还是解释器?


83

我对JVM有一个非常基本的问题:它是编译器还是解释器?

如果它是解释器,那么JVM内部存在的JIT编译器怎么办?
如果两者都不是,那么JVM到底是什么?(我不希望将字节码转换为机器特定的代码等jVM的基本定义。)


16
JVM是虚拟机。Bytcode进入后,该程序的可见效果就会发生。其他所有内容都是实现细节。

1
是的,没有“ the” JVM,该规范有多种实现。
paxdiablo

@delnan,请写下来作为答案。我真的很想赞成这样的答案。
aioobe 2011年

@aioobe:我不会。我认为它不能回答这里提出的问题-这是一个非常有用的观点,但是这个问题(在标题和文章中清楚说明)明确要求这些实现细节。

很公平。我会说这“如果两者都不是,那么JVM到底是什么?”的答案虽然部分。(因为Java虚拟机更多的是规范而不是实现。)
aioobe 2011年

Answers:


170

首先,让我们对以下术语有一个清晰的认识

Javac是Java编译器-将Java代码编译为Bytecode

JVM是Java虚拟机-运行/解释/将字节码转换为本机代码

JIT是即时编译器-在运行本机代码之前,将给定的字节码指令序列在运行时编译为机器代码。它的主要目的是对性能进行重大优化。

现在,让我们找到您问题的答案。

1)JVM: is it a compiler or an interpreter? -答案:口译员

2)what about JIT compiler that exist inside the JVM? -答:如果您完整阅读了此回复,则可能现在知道了

3)what exactly is the JVM? -答:

  • JVM是驻留在您的RAM中的虚拟平台
  • 它的组件,类加载器.class文件加载到RAM中
  • JVM中的字节码验证程序组件检查代码中是否存在任何访问限制冲突。(这是Java安全的原则原因之一)
  • 接下来,执行引擎组件将字节码转换为可执行的机器代码

希望这对您有所帮助。


您说JVM将字节码转换为本机代码。我不确定“翻译”一词在这里是否正确。
Koray Tugay,2015年

高度赞赏。您几乎消除了我对编译和解释,字节码和m / c码之间差异的怀疑。您的回答告诉我,解释器将字节码转换为机器代码,然后编译器将源代码转换为字节码。
Harsimer's

2
您还可以告诉我什么是本机代码吗?这是否意味着机器代码?我正在尝试学习整个编译和解释过程,但是这些中间术语非常令人困惑。
Harsimer '16

6
因此,JVM和JIT都将字节代码转换为平台特定的机器代码。它们之间有什么区别?你能广泛解释一下吗?
Aditya

6
“运行/解释/将字节码转换为本机代码”是胡说八道。这无论是“运行/解释”“字节码转换成机器码”。两者不能同时使用。
罗恩侯爵

32

两者都有一点,但传统意义上都不是。

现代JVM使用字节码,并在首次需要时将其编译为本地代码。在本文中,“ JIT”代表“及时”。它从外部充当解释器,但实际上它是在幕后被编译为机器代码。

JVM不应与Java编译器混淆,后者会将源代码编译为字节码。因此,将其视为“编译器”不是有用的,而是知道它在后台确实进行了一些编译。


8
@NaeemShah:我很受宠若惊,因为您足够喜欢这个答案,几乎可以逐字逐句地将其复制到您自己名字下的博客文章中。并且您有权这样做,但是根据StackOverflow的许可计划,法律上要求您将所有权归还给此处,并且您必须以相同的许可来许可您的博客文章。请参阅此网站的页脚,该页脚链接到以下许可证:creativecommons.org/licenses/by-sa/3.0。另请参阅此博客文章:blog.stackoverflow.com/2009/06/attribution-required
Mark Peters

8

就像@delnan在评论部分已经说过的,两者都不是

JVM是运行Java字节码的抽象机。

JVM有几种实现:

  • HotSpot(解释器+ JIT编译器)
  • Dalvik(解释器+ JIT编译器)
  • ARTAOT编译器+ JIT编译器)
  • GCJ(AOT编译器)
  • JamVM(解释器)

...还有许多其他

在谈论JVM时,其他大多数答案都涉及HotSpot或上述实现JVM方法的某种混合。


1
艺术也是一个解释:“机器人可以实际运行.dex通过解释和刚刚在实时(JIT)编译...直接代码”source.android.com/devices/tech/ota/ab/...
伊尔凡·拉蒂夫

5

两者都是。它从解释字节码开始,并且可以(应该确定是否值得)然后将该字节码编译为本地机器代码。


您可能是指HotSpot
cubuspl42 '19

5

都是。它可以解释字节码,并将其编译为本地代码。



0

Javac是编译器,而不是传统的编译器。编译器通常将源代码转换为机器级语言以供执行,并且只需一次操作即可完成,即在ONCE处获取整个代码并将其转换为机器级语言。(有关详情,请参见下文)。同时,JavaC将其转换为字节码而不是机器级语言。

JIT是Java编译器,但也可以充当解释器。典型的编译器会立即将所有代码从源代码转换为机器级别的语言。相反,JIT逐行执行(逐行执行是Interpreters的功能),并将JavaC生成的字节码转换为机器级语言并执行。带有JIT的JVM具有多种实现。热点是Java编程的主要热点之一。热点实现使JIT通过立即将重复的代码块转换为机器级语言(如上述编译器)来优化执行,从而可以更快地执行它们,而不用将代码的每一行都转换为1。关于编译器和解释器的典型定义,答案不是黑白的。

阅读一些在线答案,博客等后,这就是我的理解。如果有人对提高理解有建议,请随时提出建议。


-5

JVM同时具有编译器和解释器。因为编译器会编译代码并生成字节码。之后,解释器将字节码转换为机器可理解的代码。

示例:编写并编译程序,该程序可在Windows上运行。将.class文件带到另一个OS(Unix),它将运行,因为解释器将字节码转换为机器可理解的代码。


1
您忘记关闭Caps了:)
Aleksej Vasinov

7
错误的是,您首先将源代码编译为字节码(与JVM无关),然后JVM解释该字节码并将其编译为本地代码(但可能不是每个部分)。
The_Fox
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.