一、JVM 核心组成
JVM 主要由以下四部分组成,协同管理内存、执行字节码和资源回收:
1. 类加载子系统(Class Loader Subsystem)
- 作用:加载
.class文件到内存,生成Class对象。 - 关键流程:
- 双亲委派模型:
- 层级:
Bootstrap → Extension → Application → 自定义类加载器 - 原则:优先由父加载器加载,避免核心类被篡改。
- 层级:
2. 运行时数据区(Runtime Data Areas)
| 区域 | 作用 | 线程共享性 | 异常 |
|---|---|---|---|
| 堆(Heap) | 存储对象实例和数组,GC 主战场 | 共享 | OutOfMemoryError |
| 方法区(Metaspace) | 存储类元数据(JDK8+ 使用本地内存) | 共享 | Metaspace OOM |
| 虚拟机栈(JVM Stack) | 存储栈帧(局部变量表、操作数栈、方法出口等) | 线程私有 | StackOverflowError |
| 本地方法栈 | 为 Native 方法(如 C/C++ 代码)服务 | 线程私有 | StackOverflowError |
| 程序计数器(PC) | 记录当前线程执行的位置(唯一无 OOM 的区域) | 线程私有 | 无 |
3. 执行引擎(Execution Engine)
- 解释器:逐行解释字节码,启动速度快,执行效率低。
- 即时编译器(JIT):将热点代码编译为机器码(如 C1、C2 编译器),提升执行效率。
- 垃圾回收器(GC):自动回收堆内存中的无用对象。
4. 本地方法接口(JNI)
- 提供调用操作系统底层功能(如文件操作、网络通信)的接口。
二、垃圾回收算法与回收器
1. 垃圾回收算法
| 算法 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| 标记-清除 | 标记无用对象后清除 | 实现简单 | 内存碎片化 | 老年代(CMS) |
| 复制算法 | 将存活对象复制到另一块内存 | 无碎片,高效 | 内存利用率低(50%) | 新生代(Survivor) |
| 标记-整理 | 标记后移动存活对象到一端 | 无碎片,内存紧凑 | 移动成本高 | 老年代(G1、ZGC) |
| 分代收集 | 新生代(复制算法)+ 老年代(标记-整理) | 针对不同区域优化 | 需组合使用 | 主流 JVM |
2. 垃圾回收器对比
| 收集器 | 算法 | 特点 | 适用场景 | 参数 |
|---|---|---|---|---|
| Serial | 新生代:复制 老年代:标记-整理 | 单线程,STW 时间长 | 客户端、小内存 | -XX:+UseSerialGC |
| Parallel Scavenge | 新生代:复制 老年代:标记-整理 | 多线程,吞吐量优先 | 后台计算型应用 | -XX:+UseParallelGC |
| CMS | 标记-清除 | 并发收集,低停顿 | 响应速度敏感型应用 | -XX:+UseConcMarkSweepGC |
| G1 | 标记-整理 + 复制 | 分区化收集,可预测停顿时间 | 大内存、低延迟 | -XX:+UseG1GC |
| ZGC | 染色指针 + 读屏障 | 超低停顿(<10ms),TB 级堆 | 超大内存、极致低延迟 | -XX:+UseZGC |
三、JVM 常用命令与机制
1. 常用诊断命令
| 命令 | 功能 | 示例 |
|---|---|---|
| jps | 查看 Java 进程 PID | jps -l(显示主类全名) |
| jstat | 监控 GC、类加载、JIT 编译状态 | jstat -gcutil PID 1000 5(每 1s 输出一次,共 5 次) |
| jmap | 生成堆内存快照(Heap Dump) | jmap -dump:live,format=b,file=heap.hprof PID |
| jstack | 生成线程快照(排查死锁、线程阻塞) | jstack -l PID > thread_dump.txt |
| jinfo | 查看/修改 JVM 参数 | jinfo -flags PID |
2. 关键机制与调优参数
-
内存分配策略:
- 对象优先在 Eden 区分配:新生代内存不足时触发 Minor GC。
- 大对象直接进入老年代:通过
-XX:PretenureSizeThreshold设置阈值。 - 长期存活对象进入老年代:通过
-XX:MaxTenuringThreshold设置年龄阈值。
-
GC 调优参数:
-Xmx4g -Xms4g # 堆最大/初始内存 -XX:NewRatio=2 # 老年代:新生代=2:1 -XX:SurvivorRatio=8 # Eden:Survivor=8:1:1 -XX:+UseG1GC # 启用 G1 回收器 -XX:MaxGCPauseMillis=200 # G1 最大停顿时间目标 -XX:+PrintGCDetails # 打印 GC 详细信息
3. OOM 排查流程
- 确定 OOM 类型:根据错误日志(如
Java heap space、Metaspace)。 - 生成 Heap Dump:使用
jmap或-XX:+HeapDumpOnOutOfMemoryError。 - 分析 Dump 文件:通过 MAT(Memory Analyzer Tool) 或 VisualVM 查找内存泄漏对象。
- 定位代码问题:检查静态集合、未关闭资源(如数据库连接)、大对象分配。
四、总结
- JVM 组成:类加载、运行时数据区、执行引擎、本地方法接口。
- 垃圾回收器选择:
- 小内存/客户端:Serial / Parallel。
- 响应优先:CMS(JDK8)或 G1(JDK11+)。
- 超大堆:ZGC 。
- 核心命令:
jps、jstat、jmap、jstack。 - 调优原则:根据业务场景平衡 吞吐量、延迟 和 内存占用。
174万+

被折叠的 条评论
为什么被折叠?



