jdk1.8 主流 JVM Hotspot oracle
GC在哪里工作:
堆(Heap) —— 所有线程共用的大仓库(线程共享区)
- 作用:存真正的新对象(new 出来的东西,比如 new Student())
- 特点:
- 内存最大的一块
- 对象只要还有人用,就一直存在
- 垃圾回收(GC)主要在这里工作

什么是GC
- Minor GC:只清理新生代 → 快、频繁
- Major GC:只清理老年代 → 慢、少见
- Full GC:清理整个堆(新生代 + 老年代)→ 最慢、停顿最长
Minor GC
S0: from
S1:to
所有创建的对象会出现在Eden
Eden 空间不足时,触发了Minor GC, 会对Eden from 中的对象通过是否可以被引用和引用类型(可达性判断)判断是否存活 ,可以被引用的对象会从Eden from 中被复制到to,清空 Eden + 旧 From,To 变成新 From,每次 Eden 再满就触发一次,循环往复,只有活下来的对象年龄 +1(默认从 0 开始), 年龄达到 15(默认)→ 晋升到老年代,不触发Minor GC。
什么是可达性判断
| Strong | 强引用 | 最强 | 永远不回收(除非没有强引用) | 普通变量 Object obj = new … | 只要强引用存在,对象强可达,绝不回收 |
| Soft | 软引用 | 中等 | 内存不足时(即将 OOM)才回收 | 缓存(图片缓存、计算结果缓存) | 没有强引用时,软可达,内存紧张才回收 |
| Weak | 弱引用 | 弱 | 下一次 GC 就回收 | WeakHashMap、ThreadLocal | 没有强/软引用时,弱可达,很快被回收 |
| Phantom | 虚引用 | 最弱 | 对象被 finalize 后,在内存真正释放前回收 | 资源清理、堆外内存管理 | 虚可达,必须配合 ReferenceQueue 使用 |
强引用 通过任意类创建的对象,不可回收,除非强引用不存在 强引用=null, 方法执行结束(局部变量)
软引用=任意对象通过SoftReference封装都能成为软引用,条件为SoftReference对象不为null且由强引用持有(可以通过强引用集合)
弱引用 = 强引用消失后,下一次 GC 就回收的对象引用。
虚引用 = 强引用对象 + ReferenceQueue + PhantomReference 封装 + 必须把强引用置为 null
通过ReferenceQueue对象阻塞对象回收来接收通知
例外:大对象(比如超大数组)可能直接进入老年代,不走 Eden
什么是GC Roots
GC Roots = JVM 永远认为“活着”的起点对象。
GC 会从这些“起点”开始,遍历所有能被引用的对象,找不到的就当垃圾回收。
为什么需要 GC Roots?
JVM 使用可达性分析(Reachability Analysis)来判断对象是否是垃圾:
Major GC
Major GC与Minor GC区别
| 清理区域 | Eden + Survivor0/1 | 老年代(Old Generation) |
| 触发条件 | Eden 快满了 | 老年代空间不足(或达到阈值) |
| 频率 | 非常频繁(可能每秒几十次) | 很少见(可能几分钟甚至几小时一次) |
| 速度 | 非常快(几毫秒~几十毫秒) | 很慢(几百毫秒~几秒) |
| 停顿时间 | 很短(用户几乎感觉不到) | 很长(可能造成明显卡顿) |
| 算法 | 复制算法(Copying) | 标记-清除(Mark-Sweep) 或 标记-整理(Mark-Compact) |
| 对象特点 | 大部分对象“朝生夕死” | 长期存活的对象 + 大对象 |
Full GC
Full GC = Minor GC + Major GC 同时发生的过程,是清理整个堆的最彻底的垃圾回收。
特点:时间最长,GC优化重点
G1框架 jdk9+
G1 = 一个通过“区域化 + 垃圾优先 + 混合回收”来避免 Full GC 的现代 GC 优化框架,特别适合大堆、低延迟场景。
总结:
可达性判断
| 强引用 | 强可达 | 绝不回收 |
| 软引用 | 软可达 | 内存不足时回收 |
| 弱引用 | 弱可达 | 下次 GC 就回收 |
| 虚引用 | 虚可达 | 对象 finalize 后、内存释放前通知 |
GC类型
| Minor GC | 只清理新生代 | 非常频繁 | 很短 | 快速清理年轻对象 |
| Major GC | 只清理老年代 | 很少见 | 较长 | 深度清理老对象 |
| Full GC | 新生代 + 老年代 | 最少见 | 最长 | 整个堆大扫除 |
G1 适合什么场景?
- 大堆(8GB 以上)
- 需要低延迟(响应时间敏感的服务)
- JDK 9+(默认就是 G1)
- 不想频繁 Full GC 的系统


