一. 背景介绍
笔者在这个系列的第一篇文章《一文看懂"ParNew+CMS"垃圾回收器》中详细介绍了"ParNew+CMS"垃圾回收器的工作原理。文章最后笔者提到CMS垃圾回收器有两个比较显著的问题,一个是长时间运行无法避免Full GC,一个是Remark阶段STW时间较长。正是因为这两个问题的存在,CMS垃圾回收器在JDK9被标记弃用,慢慢开始退出历史舞台。有走的,就有来的,JVM重新设计了另一款垃圾回收器G1,有效地解决了CMS垃圾回收器遇到的上述两大问题。那么,这篇文章我们就详细探讨一下G1垃圾回收器是如何解决上述两大问题的。
和上篇文章介绍"ParNew+CMS"垃圾回收器一样,笔者会从G1垃圾回收器最基础的数据结构和算法出发,深入分析它的工作原理,对其中的一些关键机制进行剖析。
二. G1回收器核心数据结构
1.1 Regio
为什么CMS垃圾回收器长时间运行无法避免FGC?本质是因为CMS垃圾回收器中老年代采用标记清理算法,这种算法会产生较多内存碎片,当内存碎片很碎无法给对象分配出连续空间的时候,JVM就会触发FGC整理老年代。那有些同学就会问为什么不在每次老年代GC的时候执行整理操作呢?这主要是因为老年代如果很大的话,整理一次STW的时间会不可控。那怎么破这个局呢?JVM设计者提出了一个思路老年代不是很大吗,那就将老年代划分成很多小的格子,在此基础上GC算法基本不变,还是先标记,不过在标记完成后,按照优先级选择部分格子使用复制算法进行整理,这样每次整理的内存空间是可控...