JVM体系架构
JVM是什么
JVM全称Java Virtual Machine(Java虚拟机),是一个虚构出来的计算机,它屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码,ByteCode), 就可以在多种平台上不加修改地运行。这背后其实就是JVM把字节码翻译成具体平台上的机器指令,从而实现“一次编写,到处运行(Write Once, Run Anywhere)”。
JVM架构图
JVM-Architecture.pngJVM工作机制
如上面的架构图所示,JVM分成四个主要的子系统:
- 类加载器
- 运行时数据区
- 执行引擎
- 本地方法调用
类加载器
Java的动态类加载功能由类加载器子系统处理。它加载,链接,并在类运行时第一次引用类时初始化类文件,而不是编译时。
1.1 加载
通过类加载器实现类的加载动作,绝大部分Java程序都会使用到以下三种系统提供的类加载器:
- 启动类加载器(Bootstrap ClassLoader)
- 扩展类加载器(Extension ClassLoader)
- 应用程序类加载器(Application ClassLoader)
上面的类加载器将在加载类文件时遵循委托层次结构算法。
1.2 链接
- 验证 确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
- 准备 正式为类变量分配内存并设置初始值的阶段,这些变量所使用的内存都将在方法区中进行分配
- 解析 虚拟机将常量池内的符号引用替换为直接引用的过程
1.3 初始化
这是类加载的最后阶段,为所有的变量分配原始值,并执行静态代码块
运行时数据区
Java虚拟机在运行程序的过程中会把它所管理的内存划分为若干个不同的数据区。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有的区域则依赖用户线程的启动和结束而建立和销毁。
程序计数器
一块较小的内存空间,可以看作是当前线程所执行的字节码行号指示器
Java虚拟机栈
Java虚拟机栈描述的是Java方法执行的内存模型,每个方法在执行的同时都会创建一个站帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
本地方法栈
本地方法栈与虚拟机栈发挥的作用类似,虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用的Native方法服务。
Java堆
Java堆是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。
Java堆是垃圾收集器管理的主要区域,因此很多时候也称作GC堆。
方法区
与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
执行引擎
执行通过类加载器分配给运行时数据区的字节码,并将这些字节码转换成JVM虚拟机更容易执行的语言。主要有三个子组件。
解释器
负责读取字节码并顺序的执行。缺点是当一个方法被多次调用时,每次都需要新的解释。
JIT(Just In Time)编译器
抵消了解释器执行缓慢的缺点。JIT编译器同时编译字节码的重复部分,总而减少编译所需的总时间。从而提高性能。
- 中间代码生成器 负责生成中间代码
- 代码优化器 负责优化上面生成的中间代码
- 目标代码生成器 负责生成机器代码或本机代码
- Profiler 一个特殊组件,负责查找热点,即是否被多次调用
垃圾收集器
收集和删除未引用的对象来释放内存。可以通过调用触发垃圾收集System.gc(),但不保证执行。
本地方法接口
JNI与本地方法库交互,并提供执行引擎所需的本地库
本地方法库
执行引擎所需要的本地库的集合