NOTICE:本文仅记录本人对 JVM G1 的小小理解,没有详细记录每个点,若有误可指出
内存区域
G1 将堆分为各个 region,大小通过 G1HeapRegionSize 指定
region 分类
按 region 大小分
普通 region,存放大小小于普通 refion 容量的一半的对象
humongous 区域,存放大对象
按功能来分
新老代
老年代(humongous 只能在老年代)
新对象进入
新对象根据大小进入普通 region /humongous
-
记忆集维护
本 region 维护一个记忆集,记忆集都是别的 region 对象指向本 region 的引用
写前屏障,处理 SATB,将修改前引用对象放入 SATB 队列
写后屏障,标记被修改的对象所在卡表为 dirty card
垃圾回收
回收依据
维护每个 region 中垃圾的价值(回收获得的空间大小以及所需时间的比值)大小,通过最大 GC 时间(-XX:MaxGCPauseMillis)优先处理价值大的 region
回收分类
Young GC
Mixed GC(老年代中的内存比例超过IHOP)
回收步骤
-
初始标记
标记 GC Root 直接关联的对象
生成原始快照
修改 TAMS 的值
需要 Stop the world
-
并发标记
从 GC Root 开始进行可达性分析
处理 SATB 记录的引用变动的对象
-
最终标记
- 处于并发阶段遗留的少量 SATB 记录
-
筛选回收
计算各个 region 回收价值
-
回收
将回收 region 中存活对象挪到空 region 中
清空原有 region
标记过程中问题处理
-
在并发标记中,有新对象生成
通过 TAMS 划分特定区域
新对象只能放在 TAMS 区域中,并且默认是黑色的
-
在并发标记进行可达性分析,引用变动的对象处理
使用 SATB 记录灰色到白色删除的引用
在最终标记以灰色的对象为根,重新扫描一次
概念解释
三色标记法
黑色意义为被访问过的对象,引用都扫描过,并且确认最后是存活的,GC Root 默认为黑色
灰色意义为被访问过的对象,有一个引用未被扫描过,未确定是否存活
白色意义为未被访问过的对象
对并发标记中对象引用变化处理
SATB
全称为 Snapshot At The Beginning
-
Region 包含 5 个指针
bottom
previous TAMS
next TAMS
top
end
-
作用流程
并发标记中,新创建的对象在 next TAMS -> top 之间,此区间默认为黑色,默认存活
灰色对象删除指向白色的引用,记录下来
以记录下来的灰色为根,重新扫描
Incremental Update
黑色插入新的指向白色的引用,记录下来
并发扫描结束后,以记录下来的黑色为根,重新扫描一遍
参考
https://blog.51cto.com/u_15072811/4679940
本文首发于cartoon的博客