如果一个人对于不同的架构需要不同的JVM,我就不知道引入这个概念背后的逻辑是什么。在其他语言中,不同的机器需要不同的编译器,但在Java中,我们需要不同的JVM,那么引入JVM概念或这个额外步骤背后的逻辑是什么呢?
发布于 2017-04-03 13:50:50
逻辑是JVM字节码比Java源代码简单得多。
在高度抽象的层次上,编译器可以被认为有三个基本部分:解析、语义分析和代码生成。
解析包括读取代码并将其转换为编译器内存中的树表示形式。语义分析是它分析这棵树的一部分,它指出了它的含义,并将所有高层结构简化为低级结构。代码生成采用简化树,并将其写入一个平面输出。
有了字节码文件,解析阶段就大大简化了,因为它是用JIT使用的相同的扁平字节流格式编写的,而不是递归的(树结构的)源语言。此外,许多语义分析的繁重工作已经由Java (或其他语言)编译器执行。所以它所要做的就是流读取代码,进行最小的解析和最小的语义分析,然后执行代码生成。
这使得JIT必须执行的任务要简单得多,因此执行起来要快得多,同时仍然保留高级别的元数据和语义信息,这使得理论上能够编写单源、跨平台的代码。
发布于 2017-04-03 13:54:27
各种类型的中间表示在编译器/运行时设计中越来越常见,原因如下。
在Java的例子中,最初的首要原因可能是可移植性:Java最初被大力宣传为“编写一次,在任何地方运行”。虽然您可以通过分发源代码和使用不同的编译器针对不同的平台来实现这一点,但这有一些缺点:
中间代表的其他优势包括:
发布于 2017-04-03 17:40:21
听起来你在想为什么我们不只是分发源代码。让我把这个问题转过来:为什么我们不直接分发机器代码呢?
显然,这里的答案是,Java在设计上并不认为它知道您的代码运行的机器是什么;它可能是一台桌面、一台超级计算机、一部电话,或者是介于两者之间的任何东西。Java为本地JVM编译器提供了做它的事情的空间。除了增加代码的可移植性之外,这还可以让编译器做一些事情,比如利用特定于机器的优化,如果它们存在的话,或者如果它们不存在的话,至少仍然可以产生工作代码。像SSE指令或硬件加速之类的东西只能在支持它们的机器上使用。
从这个角度看,对原始源代码使用字节码的理由更加清晰。尽可能接近原始机器语言可以让我们实现或部分实现机器代码的一些好处,例如:
请注意,我没有提到更快的执行。源代码和字节代码都是或可以(理论上)完全编译到同一台机器代码中,以便实际执行。
此外,字节码还允许对机器代码进行一些改进。当然,还有我前面提到的平台无关性和特定于硬件的优化,但是也有一些东西,比如为JVM编译器提供服务,以便从旧代码中生成新的执行路径。这可以是修补安全问题,或者如果发现了新的优化,或者利用新的硬件指令。在实践中,很少会看到这样的大变化,因为它可以暴露big,但这是可能的,而且它总是以小的方式发生。
https://softwareengineering.stackexchange.com/questions/345458
复制相似问题