说说G1垃圾收集器
G1概览
G1 GC 全称是Garbage First Garbage Collector,垃圾优先垃圾回收器,以下简称G1。
G1是HotSpot JVM的
短停顿垃圾回收器
。其实关于G1的论文早在2004年就有了,但是G1是在2012年4月发布的
JDK 7u4
中才实现。从长期来说,G1旨在
取代CMS
(Concurrent Mark Sweep)垃圾回收器。G1从JDK9开始已经作为
默认的垃圾回收器
。如果对于应用程序来说停顿时间比吞吐量更重要,G1是非常合适的选择。
总体来说G1具有如下特点:
- G1仍旧是分代(年轻代,老年代)的垃圾回收器
- G1实现了两种垃圾回收算法 ->
标记-复制算法
+标记-整理算法
- G1不用一次性将堆中的垃圾都回收,G1会动态选择垃圾多的一块内存优先回收
- 并且可以指定期望的停顿时间
G1垃圾回收的创新设计
内存布局
G1
虽然仍旧是分代(年轻代,老年代)的垃圾回收器,但不再遵循之前的堆中对象的分代排列,而是将堆分成若干个等大的区域。
而是变成:
将堆内存均衡为小块内存(Region),这个小块(Region)是多大是可以控制的
通过参数
-XX:G1HeapRegionSize=n
可指定分区大小(1MB~32MB,且必须是2的幂)默认将整堆划分为2048个分区 -> 如果堆是2g,那么每一个小块(Region)就是1M
Humongous
:当你分配的一个对象超过一半区域(Region)的大小时(超过0.5M时),这个对象就会被放入这个区域。这个区域属于老年代区域。
G1垃圾回收过程
G1垃圾回收主要包括2个:
- 新生代回收过程(young gc) -> 回收
- 应用程序分配内存,当新生代的Eden区用尽时开始新生代回收过程
- 混合回收过程(mixed gc) -> 回收
- 当堆内存使用达到一定值(默认45%)时,开始老年代并发标记过程 ,标记完成马上开始混合回收过程。
新生代回收过程
大致的逻辑不会有太大变化:
存活的对象被转移到一个/或多个survivor 块上去。 如果存活时间达到阀值,这部分对象就会被晋升到老年代。
混合回收过程
-
初始标记
仅仅标记GC roots能直接关联到的对象。该步骤需要STW,但是时间极短。 -
并发标记
从GC roots使用可达性算法,对堆内存中对象进行标记(三色标记法
),递归扫描整个堆。该步骤耗时过长,是与用户业务程序并发执行。 -
重新标记
对用户线程短暂的STW,用于处理并发标记中对象的一些变更情况的最终确定。 -
筛选回收
G1会根据用户规定的停顿时间,最大的回收region,将需要被回收的region复制到空白region中,再将原region全部回收。该步骤也需要STW,因为涉及到了对象的移动(一个region到另一个region)。