JVM基础--JVM的组成
目录
前言
JVM整体架构
1. 类装载器子系统(Class Loader Subsystem)
1.1 装载(Loading)
1.2 链接(Linking)
1.3 初始化(Initialization)
2. 运行时数据区域(Runtime Data Area)
2.1 线程共享区域
方法区(Method Area)
堆(Heap)编辑
2.2 线程私有区域
程序计数器(PC Register)
Java虚拟机栈(JVM Stack)
本地方法栈(Native Method Stack)
3. 执行引擎(Execution Engine)
3.1 解释器(Interpreter)
3.2 即时编译器(JIT Compiler)
3.3 垃圾收集器(Garbage Collector)
4. JVM内存模型示意图
5. 实际应用中的调优建议
5.1 堆内存调优
5.2 垃圾收集器选择
5.3 JIT编译优化
总结
前言
Java虚拟机(JVM)作为Java语言的核心基础设施,承担着将Java字节码转换为机器码并执行的重要职责。理解JVM的组成结构,对于Java开发者来说至关重要,它不仅能帮助我们写出更高效的代码,还能在遇到性能问题时快速定位和解决。本文将详细介绍JVM的各个组成部分及其工作原理。
JVM整体架构
JVM可以分为三大主要区域:
- 类装载器子系统(Class Loader Subsystem)
- 运行时数据区域(Runtime Data Area)
- 执行引擎(Execution Engine)
让我们逐一深入了解这些组件。
1. 类装载器子系统(Class Loader Subsystem)
类装载器负责将.class
文件加载到JVM内存中,这个过程包含三个步骤:
1.1 装载(Loading)
- 启动类装载器(Bootstrap ClassLoader):加载核心Java API(如
java.lang.*
包) - 扩展类装载器(Extension ClassLoader):加载扩展目录中的类库
- 应用程序类装载器(Application ClassLoader):加载用户自定义的类
1.2 链接(Linking)
- 验证(Verification):确保字节码文件的正确性
- 准备(Preparation):为类变量分配内存并设置默认初始值
- 解析(Resolution):将符号引用转换为直接引用
1.3 初始化(Initialization)
执行类构造器<clinit>()
方法,完成静态变量的赋值和静态代码块的执行。
2. 运行时数据区域(Runtime Data Area)
这是JVM内存管理的核心部分,分为线程共享和线程私有两类区域。
2.1 线程共享区域
方法区(Method Area)
- 存储内容:类信息、常量、静态变量、即时编译器编译后的代码
- Java 8之前:永久代(PermGen)实现
- Java 8及之后:元空间(Metaspace)实现,使用本地内存
堆(Heap)
-
年轻代(Young Generation)
- Eden区:新对象分配的主要区域
- Survivor区:分为S0和S1,存放经过一次GC后存活的对象
-
老年代(Old Generation)
- 存放长期存活的对象
- 当对象在年轻代经过多次GC仍然存活时,会被晋升到老年代
2.2 线程私有区域
程序计数器(PC Register)
- 记录当前线程执行的字节码指令地址
- 线程切换时能够恢复到正确的执行位置
- 如果执行的是Native方法,则计数器值为空
Java虚拟机栈(JVM Stack)
每个方法执行时都会创建一个栈帧,包含:
- 局部变量表:存储方法参数和局部变量
- 操作数栈:进行算术运算的工作区域
- 动态链接:指向运行时常量池的引用
- 方法返回地址:方法正常退出或异常退出的返回信息
本地方法栈(Native Method Stack)
为虚拟机使用到的Native方法服务,与Java虚拟机栈作用类似。
3. 执行引擎(Execution Engine)
执行引擎负责执行字节码指令,主要包含以下组件:
3.1 解释器(Interpreter)
逐行解释执行字节码指令,启动快但执行效率相对较低。
3.2 即时编译器(JIT Compiler)
- 作用:将热点代码编译成本地机器码
- 优势:显著提高代码执行效率
- 类型:
- C1编译器:客户端编译器,编译速度快
- C2编译器:服务端编译器,优化程度高
3.3 垃圾收集器(Garbage Collector)
自动管理内存,回收不再使用的对象,主要算法包括:
- 标记-清除算法
- 复制算法
- 标记-整理算法
- 分代收集算法
4. JVM内存模型示意图
5. 实际应用中的调优建议
5.1 堆内存调优
# 设置堆的初始大小和最大大小
-Xms512m -Xmx2g# 设置年轻代大小
-Xmn512m# 设置Survivor区比例
-XX:SurvivorRatio=8
5.2 垃圾收集器选择
# 使用G1垃圾收集器
-XX:+UseG1GC# 设置GC停顿时间目标
-XX:MaxGCPauseMillis=200
5.3 JIT编译优化
# 设置热点代码编译阈值
-XX:CompileThreshold=10000
总结
JVM的组成结构设计精巧,各个组件协同工作,为Java程序提供了稳定高效的运行环境。理解这些组件的作用和工作原理,能够帮助开发者:
- 写出更高效的代码:了解内存分配机制,减少不必要的对象创建
- 进行性能调优:根据应用特点调整JVM参数
- 排查线上问题:快速定位内存泄漏、GC问题等
- 选择合适的垃圾收集器:根据应用场景选择最适合的GC策略