为什么JVM不能预先编译整个程序,而不是逐个编译它?

Ser*_*gey 12 java jit jvm bytecode compilation

Herbert Schildt写道:

重要的是要理解将整个Java程序一次性编译成可执行代码是不切实际的,因为Java执行各种运行时检查,只能在运行时完成.

他的意思是什么运行时检查?

请解释一块一块地编译字节码的原因,而不是整个程序.

Bil*_*l K 2

他的意思是,在运行时将所有字节码编译为机器语言是不切实际的。您可以预编译所有内容,但这不是 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;
    }
Run Code Online (Sandbox Code Playgroud)

编译器可以调用它一次或两次,并即时识别出 5 及以下的值仅返回。如果始终使用值 2 调用此函数,则可以将整个方法调用替换为 if (param != 2) testMeh(param);

这消除了对该号码的整个方法调用。后来它可以发现,不调用该方法意味着某些成员变量无法更改,并且可能会将代码的其他部分压缩为空。

如果你预编译东西,这简直是太难了。我的意思是,当您识别模式时,您可以在任何地方编写异常代码,但您的代码很快就会变成一场噩梦。

现在,如果您问为什么在将整个程序编译为字节码时不预编译整个程序 - 这是一个不同的问题,根本不是引用所解决的问题 - 但您可以这样做。它已经完成并且效果很好。您可以用可移植性和运行时灵活性来换取更快的启动时间。