g1收集器以大小固定、角色可变的region替代传统代际结构,每个region动态承担eden、survivor、old或humongous角色;回收基于垃圾密度优先选择高收益region,辅以remembered set和写屏障实现精准跨region引用追踪,并通过暂停预测模型调控停顿时间。

G1 收集器的 Region 分区不是把堆“切小了完事”,而是重构了整个内存管理逻辑——它用大小固定、角色可变的独立区域替代传统连续代际,让回收从“扫全堆”变成“挑最值钱的块来清”。
Region 是什么:灵活的多功能格子
每个 Region 大小在 1MB~32MB 之间(必须是 2 的幂次,如 2MB、4MB),总数最多 2048 个。它不预设属于年轻代还是老年代,运行时只承担一种逻辑角色:
- Eden:分配新对象
- Survivor:存放 Young GC 后存活的对象
- Old:容纳晋升后的长生命周期对象
- Humongous:专用于大对象(大小 ≥ 单个 Region 的 50%),会占用连续多个 Region
一个 Region 当前是 Eden,下次可能变成 Old;回收清空后又变为空闲 Region,随时可被重新指定角色。这种动态性打破了“代”在物理上的固化边界。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
回收不看“代”,只盯“垃圾密度”
G1 不按年轻代或老年代整体触发 GC,而是持续跟踪每个 Region 的垃圾占比(即回收价值)。它维护一个优先级列表,每次 Mixed GC 只选若干个垃圾最多、收益最高的 Old Region 加入 CSet(Collection Set)。
- Young GC 仍清理所有 Eden + Survivor Region
- Mixed GC 则混合清理:全部年轻代 Region + 部分老年代 Region
- 避免扫描整个老年代,大幅降低 STW 时间
跨 Region 引用靠 Remembered Set 精准定位
对象分布在不同 Region 中,引用关系错综复杂。G1 为每个 Region 配备 Remembered Set(记忆集),记录哪些其他 Region 里有指向本 Region 对象的引用。
- 写屏障(Write Barrier)在对象引用更新时触发记忆集更新
- 标记阶段只需查记忆集,不用扫描全堆找跨 Region 引用
- 代价是每次引用修改都有额外开销,但 G1 通过批量处理等方式优化
停顿可控,靠预测模型和参数协同
G1 的 Pause Prediction Model 会根据历史 GC 数据、Region 回收成本与收益,估算本次能回收多少 Region 才不超 -XX:MaxGCPauseMillis 设定的停顿目标。
- 这个参数不是硬性上限,而是软目标——JVM 尽量满足,但不保证绝对达标
- 设得太小会导致频繁 GC、吞吐下降;设得太大则延迟不可控
- Mixed GC 触发时机由 -XX:InitiatingHeapOccupancyPercent(默认 45%)控制,即老年代占用率达阈值时启动并发标记周期
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










