java - 如果java可以编译代码,为什么还要解释它?

标签 java compilation jvm jit jvm-hotspot

在企业应用程序中,相同的代码运行数天而无需重新启动,如果代码被多次点击,即超过阈值时间,那么无论如何它都会被即时编译(其中大部分),所以我想问为什么它一开始就没有被编译。我的意思是 jvm 工程师可以将代码编译为字节代码以保持平台独立性,并对机器代码再进行一次编译,并且在一般情况下以及当满足以下条件时,机器代码不应该更快吗?如果需要进行 jit 编译,那么 jvm 可以使用所有分析信息和统计信息来增强机器代码,并进行所有增强。当然,这会占用编译时间,但一般代码并不是每次执行时都被简单地解释。即创建一个编译器来编译并夸耀它,以防某些方法变得很热。我可能错了,但这是一个奇怪的问题。

最佳答案

优化编译的成本非常高。查看大型 C 项目(例如 Firefox、Linux 内核)的编译时间,尤其是链接时间优化。

JIT 还针对目标平台进行编译,即它们尝试使用它们可以支持的所有可用指令进行编译,这意味着您无法分发编译后的代码。

现在考虑 JIT 执行推测性优化(基于分析),这可能会出错并需要退出。如果只选择编译,则该代码在重新编译之前将无法继续运行。通过解释器,它可以继续执行导致救援的不常见代码路径。

您还必须记住,某些优化是特定于工作负载的,即(坏的)测试工作负载可能会使用与实际工作负载不同的代码路径,因此在运行时分析后进行不同的编译会受益。

并非所有应用程序都是长时间运行的守护进程。有些东西会启动 JVM 来执行单个任务,然后在完成后退出。

还要考虑到很多代码只运行一次,例如在应用程序启动或关闭期间。

所有这些因素都解释了为什么一些 JVM 默认使用解释器+编译器的组合。由于不同的技术权衡,其他人可能只使用 AOT 编译的代码或只使用解释器,但它们通常不会更快。

关于java - 如果java可以编译代码,为什么还要解释它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39108422/

相关文章:

如果不包含函数列表,C++ 程序将无法编译

java - 使用 JNI 从 C++ 调用 JAVA 方法,无参数

java - 为什么第一次调用loadClass方法时这个引用是AppClassLoader而不是MyClassLoader

java - 替换 Java 中的默认 DNS 名称解析

使用数据库的 Java Spring 身份验证,如何删除角色模型?

java - 快速平方一个双

java - 使用 Java 下载 torrent 使用什么?

java - 在 Java 中一次维护 5 个线程

c++ - 未找到符号又名 undefined symbol

c - 优化 if 语句在第一次评估后始终具有相同的值