——你必须先搞懂的底层基础(GC 调优必读)
GC 调优离不开对 JVM 内存结构的理解,本篇将从:
JVM 内存结构
对象创建与逃逸流程
垃圾回收算法
GC 触发条件
各类垃圾收集器原理(重点:G1 / ZGC)这 5 个方面给你建立完整知识体系。
🧩 一、JVM 内存结构(JAVA 8+)
自从 Java 8 移除永久代(PermGen)后,JVM 的结构更清晰了:
【线程私有】
- 程序计数器 (Program Counter)
- JVM 栈 (Stack)
- 本地方法栈 (Native Stack)
【线程共享】
- 堆 (Heap)
- 元空间 (Metaspace)
- 代码缓存 (Code Cache)我们重点讲 Heap + Metaspace,因为 GC 主要发生在堆。
✔ 1. 堆(Heap)
堆是 JVM 最大、最重要 的区域,存放所有对象。
结构如下:
Heap
├── Young Generation(新生代)
│ ├── Eden
│ ├── Survivor S0
│ └── Survivor S1
└── Old Generation(老年代)99% 的对象在 Eden 创建
Survivor 用于对象在 Young 区之间“拷贝”
经过多次 Minor GC 后,长寿命的对象进入 Old 区
✔ 2. 元空间(Metaspace)
Java 8 之后,类元信息存放在 本地内存 里,不再受堆大小影响。
元空间撑爆一般有两类原因:
动态生成类过多(如 CGLib、大量反射生成代理类)
Web 容器频繁重启导致类无法卸载
元空间 OOM 排查重点看:
jcmd <pid> VM.class_hierarchy⚙️ 二、Java 对象创建与分配流程
一个对象从创建到晋升的完整过程如下:
new → Eden 分配 → Minor GC → Survivor 复制 → 多次 Survivor → Old 区晋升核心规则:
✔ 1. 对象优先分配在 Eden
只要 Eden 有足够空间,JVM 会使用 TLAB(线程私有缓冲区)快速分配对象。
✔ 2. 大对象直接进入 Old 区
比如:
大数组
大字符串
大 Map
可通过:
-XX:PretenureSizeThreshold进行配置(仅部分 GC 生效)。
✔ 3. 长寿命对象晋升到 Old 区
通常经历 15 次 Minor GC 后晋升,可通过:
-XX:MaxTenuringThreshold控制;G1/ZGC 是动态调整,无需设置。
♻️ 三、JVM 中的垃圾回收算法(理解 GC 核心原理)
GC 的根本问题:
认识哪些对象“还活着”?
JVM 采用 可达性分析算法(Reachability Analysis):
从 GC Roots 开始找可达对象,不能被访问的对象才是“垃圾”。
GC Roots 包括:
栈帧里的引用
本地方法引用
静态成员变量
常量池
JVM 内部引用
GC 算法核心包含三个:
✔ 1. 标记-清除(Mark-Sweep)
流程:
标记 → 清除缺点:产生内存碎片。
用于:CMS 老年代等。
✔ 2. 标记-压缩(Mark-Compact)
标记 → 移动对象 → 压缩到一起减少碎片。
用于:Serial / Parallel Old 以及 G1、ZGC 等现代 GC。
✔ 3. 复制算法(Copying)
Young 区的算法:
Eden → Survivor1
Survivor1 → Survivor2适用于:
新生代存活率低
复制成本低
🔥 四、GC 类型与触发条件(为什么 GC 发生?)
✔ 1. Minor GC(年轻代 GC)
什么时候发生?
当 Eden 空间不足。
特点:
速度快
不会影响 Old 区
停顿时间短(几十毫秒级)
Minor GC 是“常态”,不是坏事。
✔ 2. Major GC / Full GC(重点关注)
触发:
Old 区空间不足
元空间不足
显式 System.gc()(可能被禁用)
大对象分配失败
CMS/G1 触发 Mixed GC
Full GC 成本高(100ms ~ 1s+),必须重点监控。
🏆 五、现代垃圾回收器(GC 的真正核心)
不同 GC 适用于不同场景。
✔ 1. Parallel GC(吞吐量优先)
特点:
默认的堆为内存大、CPU 多的场景(以前是默认)
追求吞吐量
停顿时间较长
适合:
批处理
后台任务
延迟要求不高的系统
✔ 2. CMS(低延迟)
特点:
并发标记
减少 STW
但会产生碎片
缺点使其在 Java 9 后开始被 G1 取代。
✔ 3. G1(Java 11+ 默认)
重点:分区(Region)+ 并发 + 可预测停顿
结构:
把整个堆切成多个 Region:
Young / Old 都是多个 Region 的集合
优势:
支持大堆(4G~64G 甚至以上)
Mixed GC 效率高
停顿可控
需要理解这两个概念:
(1) Mixed GC
同时回收 Young + Old(部分 Region)
(2) RSet(记忆集)
记录 Old → Young 的引用,减少扫描范围。
✔ 4. ZGC(毫秒级低延迟)
这是 GC 的未来方向。
核心理念:
并发整理
读屏障
染色指针(Colored Pointer)
暂停 < 1ms(几乎固定)
适合:
低延迟服务
高并发场景
大堆(32GB ~ TB 级别)
ZGC + 虚拟线程(Loom)= Java 未来方向。
🧠 六、为什么系统会卡顿?(从 GC 角度看)
常见原因:
❌ Minor GC 太频繁
→ Eden 太小 / 大量瞬时对象
❌ Full GC 频繁
→ Old 区溢出 / 内存泄漏
❌ CMS/G1 回收跟不上
→ 对象创建太快
❌ 元空间不足
→ 大量动态代理类
📌 七、如何选择正确的 GC?
🎯 八、总结:理解 GC 才能真正优化性能
本篇把 JVM 内存结构、GC 原理、对象分配全都讲清楚。
当你理解:
对象为什么进入 Old 区
GC 什么时候发生
为什么会 Full GC
为什么服务卡顿
你就能真正开始 GC 调优了。
默认评论
Halo系统提供的评论