17_G1 垃圾回收器的工作原理
约 809 字大约 3 分钟
2024-08-10
ParNew + CMS 的组合的痛点
无论是新生代还是老年代的垃圾回收,都或多或少的产生 Stop the world 现象,对系统的运行是有一定的影响的
所以之后对垃圾回收器的优化,都是朝着减少 Stop the World 的目标去做的
在这个基础之上,G1 垃圾回收器就运用而生了,他可以提供比 ParNew + CMS 组合更好的垃圾回收性能
G1 垃圾回收器
G1 垃圾回收器的一个特点就是把 JVM堆内存 拆分成多个大小相等的 Region,他可以同时回收新生代和老年代的对象,如下图所示
需要注意的是,G1 虽然有新生代和老年代的概念,但只是逻辑上的概念,一个 Regin 可能属于新生代也可能属于老年代

G1 还可以让我们设置一个垃圾回收的预期停顿时间
也就是我们可以直接给 G1 指定,在一个时间内垃圾回收导致的系统停顿时间不能超过多久,相当于我们可以直接控制垃圾回收对系统性能的影响了
G1 如何做到垃圾回收导致系统停顿可控的
G1 通过追踪每个 Region 的回收价值来实现的
每个 Region 里的对象多少是垃圾,如果对这个 Region 进行垃圾回收,需要耗费多少时间,可以回收多少垃圾,这个就是回收价值
G1 通过追踪发现,一个 Region 中的垃圾对象有 10MB,回收需要耗费 1 秒,另外一个 Region 中垃圾对象有 20MB,回收需要 200 毫秒,如下图

进行垃圾回收时,G1 发现最近一个时间段内,已经导致了几百毫秒的系统停顿了,现在执行一次垃圾回收,那肯定是选择回收只要 200 毫秒就能回收 200MB 垃圾的 Region
简单来说,G1 通过将内存拆分为大量的 Region,以及追踪每个 Region 可以回收对象大小和预估时间,进行垃圾回收时,对系统造成的影响控制在指定时间范围内,尽可能在有限的时间回收尽可能多的垃圾对象,这就是 G1 的核心设计思路
Region 可能属于新生代也可能属于老年代
一开始 Region 可能谁都不属于,接着分配给了新生代,放了很多新生代的对象之后触发垃圾回收,然后回收了这个 Region
下一次,这个 Region 可能分配给了老年代
所以在 G1 对应的内存模型中,Region 可能属于新生代也可能属于老年代,并没有所谓新生代给多少内存,老年代给多少内存这一说法
新生代和老年代各自的内存区域是不停变动的,由 G1 自动控制