P2 · JVM 深入(W7-10)
目标:能定位 OOM、能做基本 JVM 调优、能讲清楚 GC 算法与收集器 验收:能独立完成一次线上 OOM 排查与 GC 调优报告
一、本阶段核心知识点
1. JVM 内存结构(必背)
- 程序计数器(PC)
- 虚拟机栈(栈帧:局部变量表、操作数栈、动态链接、方法返回地址)
- 本地方法栈
- 堆:新生代(Eden + 2×Survivor) / 老年代 / 元空间(1.8 后取代永久代)
- 方法区 / 元空间:类信息、常量池、静态变量、JIT 编译产物
- 直接内存(
Unsafe/ Netty 零拷贝)
2. 对象生命周期
- 对象创建流程(类加载 → 分配内存 → 初始化 → 引用入栈)
- 对象内存布局:对象头(Mark Word + Klass Pointer) + 实例数据 + 对齐填充
- 对象访问定位:句柄 vs 直接指针(HotSpot 用直接指针)
- 4 种引用:
Strong/Soft/Weak/Phantom
3. GC 算法
- 标记-清除(碎片问题)
- 标记-整理(无碎片但停顿长)
- 复制算法(新生代用,效率高)
- 分代收集理论(弱分代假说、强分代假说、跨代引用假说)
4. GC 收集器(重点)
- Serial / Serial Old
- ParNew / CMS
- Parallel Scavenge / Parallel Old(吞吐优先)
- G1(重点:Region 模型、Remembered Set、停顿预测模型)
- ZGC(≤1ms 停顿,Region+染色指针+读屏障)
- Shenandoah
- 选型建议:JDK 8 默认 Parallel;JDK 11+ 默认 G1;JDK 17+ 可用 ZGC
5. 类加载机制
- 7 个阶段:加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载
- 双亲委派模型(Bootstrap → ExtClassLoader → AppClassLoader → 自定义)
- 打破双亲委派的场景:Tomcat WebAppClassLoader、JDBC SPI、OSGi
- 类初始化的 5 种触发场景
6. 字节码与 JIT
- class 文件结构(魔数、常量池、字段表、方法表、属性表)
- 字节码指令(
aload、invokevirtual、iinc等) - JIT:C1 / C2 编译器、热点探测、分层编译
- 方法内联、逃逸分析、栈上分配、锁消除
7. 调优工具
- 命令行:
jps/jstat/jinfo/jmap/jstack/jhat/jcmd - 可视化:JConsole / VisualVM / JMC
- 阿里 arthas:
dashboard/thread/trace/watch/jad/ognl - 调优实战:堆内存设置 / GC 日志解读 / 线程 dump 分析
二、任务清单(可勾选打卡)
Week 7 · 内存模型与对象
- 手画 JVM 内存结构图(含 PC/栈/堆/方法区/直接内存)
- 演示 4 种引用类型(强软弱虚)的 GC 回收时机
- 用
JOL打印对象头 Mark Word,分析锁状态 - 写 demo:模拟
StackOverflowError与OOMError各一次
Week 8 · GC 算法与收集器
- 列出所有 GC 收集器与适用场景对比表
- 精读 G1 源码(一周):Region 模型 + Remembered Set
- 用
-Xlog:gc*跑 8 种收集器日志,读懂 GC 日志 - 跑 ZGC demo,对比 G1 的停顿时间(用
jfr)
Week 9 · 类加载与字节码
- 写 demo:自定义 ClassLoader 加载加密 class 文件
- 模拟 Tomcat WebAppClassLoader 打破双亲委派
- 用
javap -c反编译一段代码,读懂字节码指令 - 演示 5 种类初始化的触发场景
Week 10 · 调优与排障实战
- 写 demo:制造内存泄漏(线程池未关闭 / ThreadLocal 不 remove)
- 用 arthas 的
dashboard/thread排查上面的内存泄漏 - 用
MAT分析 heap dump,找到泄漏对象 GC Root - 用
AsyncProfiler打 CPU 火焰图,找到热点方法 - 写一份完整的「OOM 排查复盘报告」(截图 + 命令 + 结论)
三、阶段验收标准
✅ 能独立完成: - 现场画 JVM 内存图,说明对象创建到回收的完整路径 - 给出 5 种收集器的适用场景与停顿特点 - 解释双亲委派模型 + 至少 2 个打破的场景 - 用 arthas 演示定位一个线程阻塞 / CPU 飙升问题 - 输出 1 份"线上 OOM 排查复盘"作为面试素材
四、产出物
notes/P2-week7-内存模型.mdnotes/P2-week8-GC收集器.mdnotes/P2-week9-类加载与字节码.mdnotes/P2-week10-调优与排障.mddemo/oom-leak/内存泄漏复现 + 排查脚本report/OOM排查复盘报告.md
五、面试高频问题预告
- Java 内存模型(JMM) vs JVM 内存结构(运行时数据区) 区别?
- 为什么用元空间代替永久代?
- G1 怎么做到可预测停顿?
- 什么是三色标记?CMS 的 remark 阶段为什么必需?
- 怎么查看线程死锁?线上 CPU 100% 怎么排查?