JVM虚拟机是什么
Java Virtual Machine Java程序的运行环境(java二进制字节码的运行环境)
JVM虚拟机的组成
JVM由类加载器、运行时数据区、JVM解释器、JIT即时编译器、垃圾回收器、本地方法库等部分组成
1、类加载器(Class Loader)
字节码必须通过类加载器,通过加载、验证、解析等校验步骤,将字节码文件中的类,加载到JVM中的运行时数据区,才可以执行字节码
2、运行时数据区(Runtime Data Area)
把字节码加载到内存中,而字节码文件只是 JVM 的一套指令集规范,并不能直接交给底层系统去执行,而是有执行引擎运行
3、执行引擎(Execution Engine)
将字节码翻译为底层系统指令,再交由CPU执行去执行,此时需要调用其他语言的本地库接口(Native Method Library)来实现整个程序的功能。
4、JVM解释器(Interpreter)
JVM 的执行方式以解释执行为主。执行过程中, JVM 将每个字节码文件中的每个指令,通过
解释器转换成当前平台可以识别的机器码,然后交给 CPU 执行。
5、JIT即时编译器(Just In Time Compiler)
为了提高执行效率,JVM还会在运行期间,JVM通过热点代码的统计分析,识别高频的方法调用,循环体、公共模块等,当超过阈值时,JVM会基于JIT即时编译器将热点代码转换成机器码,直接交给CPU执行
6、程序计数器(Program Counter Register)
- 程序计数器是线程私有的,内部保存的字节码的行号。用于记录正在执行的字节码指令的地址。它是唯一没有OutOfMemoryError异常的区域。
- 程序计数器的作用可以看做是当前线程所执行的字节码的行号指示器,字节码解释器工作时就是通过改变计数器的值来选取下一条字节码指令。其中,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖计数器来完成。
- Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。
- 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Natvie方法,这个计数器值则为空(Undefined)。
7、垃圾回收器(Garbage Collctor)
JVM 在运行期间,通过 Garbage Collctor 垃圾收集器,定期对运行时数据区进行垃圾对象的回收,从而实现了内存自动管理。
JVM虚拟机各部分工作流程
由类加载器完成字节码文件的加载验证和解析,存储至运行时数据区,而字节码文件时JVM的一套指令集规范,并不能直接交给底层操作系统去执行,而后执行引擎中的解释器,完成字节码到机器码的解释执行。同时进行热点代码的统计分析,调用JIT即时编译器将字节码直接编译成机器码,提高执行效率,这个过程中需要调用其他语言的接口本地库接口来实现整个程序的功能,JVM运行期间的方法调用、数据对象统一存放在运行时数据区。