为什么JVM不预先编译整个程序,而不是逐个编译它?
对于这个帖子,赫伯特·希尔德特写道:
重要的是要了解,一次将整个Java程序编译为可执行代码是不切实际的,因为Java执行各种运行时检查,这些检查只能在运行时完成。
他指的是什么运行时检查?
请解释逐个编译字节码的原因,而不是整个程序。
对于这个帖子,赫伯特·希尔德特写道:
重要的是要了解,一次将整个Java程序编译为可执行代码是不切实际的,因为Java执行各种运行时检查,这些检查只能在运行时完成。
他指的是什么运行时检查?
请解释逐个编译字节码的原因,而不是整个程序。
可能有几个原因可以逐个编译它(这是我想到的前两个):
我不知道这个网站是否准确,但我从中学到了很多东西:http://www.artima.com/insidejvm/ed2/index.html
他说的是,在运行时将所有字节码编译为机器语言是不切实际的。您可以预编译所有内容,但这不是JIT采用的方法。
首先,不知道程序有多大。人们会在30分钟的启动中相当沮丧,因为它编译了它能找到的每个库(给定的Java程序不在单个文件中,它可以访问类路径中的所有内容)
另一方面,即使你告诉系统你的程序将使用哪些组件,也不知道你的程序有多少可以用于给定的运行 - 人们在30分钟的启动中运行一个参数由“--help”组成的命令行程序会更加沮丧。
最后,它可以通过在运行时进行编译来做一些很棒的技巧。使用如下方法:
public testMeh(int param) {
if(param == 35)
do bunches of crap;
else if (param > 5)
do much more crap;
else
return;
}
编译器可以调用它一次或两次,并动态识别值 5 及以下只是返回。如果一直以 2 的值调用它,则可以将整个方法调用替换为 if (param != 2) testMeh(param);
这消除了对该数字的整个方法调用。稍后它可以发现,不调用该方法意味着某些成员变量无法更改,并且可以将代码的其他部分折叠为零。
如果你预编译东西,这简直很难。我的意思是,当你识别模式时,你可以在任何地方编写异常代码,但你的代码很快就会变成一场噩梦。
现在,如果你问为什么不在将整个程序编译成字节码时对其进行预编译 - 这是一个不同的问题,而不是引用所解决的问题 - 但你可以这样做。它已经完成了,效果很好。您可以牺牲可移植性和运行时灵活性,以缩短启动时间。