JVM之【执行引擎系统】
目录
前言
执行引擎的作用
执行引擎主要的执行技术
解释执行
静态编译
即时编译
自适应优化
执行引擎的主要组成部分
热点探测技术
方法调用计数器
回边计数器
执行引擎的工作过程
编译器
Java中的编译器分类
HotSpot虚拟机中内嵌的JIT即时编译器
相关的JVM参数
前言
Java是一门高级语言,用Java编写的源代码通过javac前端编译器生成的class字节码文件通过JVM加载进内存,但是字节码并非机器指令并不能被计算机直接执行,那么一个Java程序能够运行在操作系统上的原因就是依赖于JVM的执行引擎系统,本文主要介绍JVM的执行引擎系统
执行引擎的作用
主要任务是通过解释器或者后端编译器(JIT即时编译器)将字节码指令转换为本地机器指令,可以将JVM执行引擎看作是JVM和操作系统之间的翻译官
执行引擎主要的执行技术
解释执行
程序运行过程中,每当用到某处代码时,才会将该代码转换为机器码交给计算机执行
静态编译
程序启动前,根据所在的硬件平台将所有的代码全部编译成对应的机器码
即时编译
程序运行过程中,通过热点探测等技术动态探测出执行比较频繁的代码,将其转化为机器码存储在热点缓存区,下次执行时直接执行机器码
自适应优化
开始时对代码都采取解释执行,启动一个后台线程将经常调用的代码编译为本地代码,如果代码不再频繁调用,则取消编译过的代码,继续采用解释执行
执行引擎的主要组成部分
JVM执行引擎包含两种执行器
- 解释器
- JIT即时编译器
当执行引擎获取到由javac编译后的字节码文件后,在运行时是通过解释器转换为机器码,为了提高效率,JVM加入了JIT即时编译器技术,目的是为了避免一些经常执行的代码被解释执行,JIT即时编译器会将频繁执行的代码编译成本地机器码,很大程度上提高了执行的效率
热点探测技术
通过热点探测技术来判断哪些是执行比较频繁的代码
方法调用计数器
当一个方法被调用时,先判断该方法是否被JIT即时编译器编译过,是的话就直接执行上次编译后生成的本地机器指令,否则先对方法调用次数+1,如果没有达到阈值,就采用解释器模式执行,如果达到了阈值,就通过JIT即时编译器后台编译生成本地机器码放入到CodeCache中缓存(热点代码缓存区,存放于元空间中),下次调用方法时直接从缓存中读取。Client模式的编译器阈值默认为1500,Server模式的编译器阈值默认为10000次
回边计数器
方法中的循环体被执行的次数
执行引擎的工作过程
执行引擎接收的输入内容必须为字节码的二进制流数据,输出内容必须为程序的执行结果;执行引擎需要执行什么操作依赖于PC寄存器(程序计数器),每当执行引擎处理完一项指令操作后,程序计数器就要更新到下一条要执行的指令地址
HotSpot虚拟机是基于栈式模型的,也就是执行引擎在执行方法时执行的是一个一个的栈帧,栈帧中包含局部变量表、操作数栈、动态链接及方法返回地址等信息,但执行引擎在JVM运行时只会执行最顶层的栈帧,最顶层的栈帧代表的是当前要执行的方法,执行完当前方法后弹出顶部栈帧,下一个栈帧成为新的顶部栈帧继续执行
编译器
Java中的编译器分类
- 前端编译器:javac,就是将.java源代码编译成.class字节码指令的编译器
- 后端编译器:JIT即时编译器,把字节码指令编译为机器指令的编译器
HotSpot虚拟机中内嵌的JIT即时编译器
- Client Compiler:Client模式的编译器
- Server Compiler:Server模式的编译器
相关的JVM参数
- [-Xint]:采用解释器模式执行程序
- [-Xcomp]:采用JIT即时编译器执行程序
- [-Xmixed]:采用解释器+JIT即时编译器的混合模式执行程序(默认的执行方式)
- [-XX:CompileThreshold]:指定热点代码阈值
- [-client]:指定JVM运行时采用Client模式
- [-server]:指定JVM运行时采用Server模式
- [-XX:ReservedCodeCacheSize]:指定CodeCache热点代码缓存区的最大大小