JVM执行模式

文章来源:https://www.cnblogs.com/heavenbird/articles/9494275.html

解释执行和编译执行

解释执行

解释执行:通过解释器将源语言代码逐条解释成机器语言,然后提交给计算机执行,解释一条执行一条,不形成目标程序,不依赖于平台
如在终端上打一条命令或语句,解释程序就立即将此语句解释成一条或几条指令并提交硬件立即执行且将执行结果反映到终端,从终端把命令打入后,就能立即得到计算结果。这种工作方式很适合于人通过终端设备与计算机交互。

缺点:解析需要时间,不生成目标程序,而是一句一句的执行的方式会造成计算机资源的浪费,即执行效率低。

编译执行

编译执行:由编译器将目标代码一次性全部编译成目标程序,再由机器运行目标程序。相比解释执行编译执行效率高,占用资源小,适合复杂程序。

编译过程是:先分析(词法分析和语法分析),后综合(优化代码,存储分配和目标代码生成),从而得到目标程序。为了完成这些分析综合任务,编译程序采用对源程序进行多次扫描的办法,每次扫描集中完成一项或几项任务,也有一项任务分散到几次扫描去完成的。编译的过程需要花费时间,编译后的机器码具有平台相关性,运行速度快。

缺点:兼容性差

通俗的比喻

编译执行相当于做好一桌子菜再开吃,而解释执行就是吃火锅,一边煮一边吃。

JVM的执行模式

java通常java分为编译期和运行时。编译期就是通过javac编译器将java源代码文件生成.class文件,.class文件里面实际上是字节码,而不是可以执行的机器码。运行时,JVM 会通过类加载器(Class-Loader)加载字节码,解释或者编译执行。启动JVM时加上-XX:PrintCompilation参数能看到相关的信息。

Java 是解释执行?

对于Java 是解释执行的这个说法其实不太准确。java的源代码首先通过javac编译器编译成字节码(bytecode),然后在运行时,通过JVM内嵌的解释器将字节码转换成最终的机器码,这时候看起来是解释执行的,但是常见的JVM(例如HotSpot JVM)都提供了JIT(Just-In-Time)编译器(即动态编译器),它能够在运行时将热点代码编译成机器码,然后缓存在codecach中,需要的时候直接去codecach中取即可,而不用再次编译。这种情况下这些热点代码就属于编译执行而不是解释执行。

JVM的四种种执行模式

JVM目前支持四种执行模式:

  • 解释模式
  • 编译模式
  • 混合模式
  • AOT(Ahead-of-Time Compilation)
    在JVM启动时,可以指定不同的参数选择不同的执行模式。新版本的JDK(例如JDK8)默认采用的是混合模式。

解释模式

JVM启动时,指定-Xint参数,就是告诉JVM只进行解释执行,不对代码进行编译。这种模式抛弃了JIT可能带来的性能优势。毕竟解释器是逐条读入,逐条解释执行的。

编译模式

JVM启动时,指定-Xcomp参数,就是告诉JVM关闭解释器,使用编译模式(或者叫最大优化级别),不进行解释执行。这种模式并不表示执行效率最高,它会导致JVM启动变得非常慢,同时有些JIT编译器的优化操作(如分支预测)并不能进行有效的优化。

混合模式

混合模式,就是解释和编译混合的一种模式,新版本的JDK(例如JDK8)默认采用的是混合模式(JVM参数为-Xmixed)。通常运行在server模式的JVM,会进行上万次调用以收集足够的信息进行高效的编译,client模式这个限制是1500次。Hotspot JVM内置了两个不同的JIT编译器,C1对应client模式,适用于对于启动速度敏感的应用(如java桌面应用);C2对应server模式,它的优化是为长时间运行的服务器端应用设计的。

AOT(Ahead-of-Time Compilation)

AOT就是将javac编译器编译后的字节码直接编译成机器代码,避免了JIT预热等各方面的开销。Oracle JDK 9就引入了实验性的AOT特性,并增加了新的jaotc工具。

将某个类或者摸个模块编译成AOT库

jaotc --output libHelloWorld.so Helloworld.class  
jaotc --output libjava.base.so --module java.base

在启动的时候直接指定

java -XX:AOTLibrary=./libHelloWorld.so,libjava.base.so HelloWorld
posted @ 2021-09-23 18:20  CodeSweet  阅读(167)  评论(0编辑  收藏  举报