最全面的 G1 学习笔记
发布网友
发布时间:2024-10-23 20:56
我来回答
共1个回答
热心网友
时间:2024-11-19 03:25
在 G1 收集器之前,CMS 算是一款优秀的收集器,它以并发收集和低停顿为优点,但也存在缺点。设计团队为了改进这些不足,开发了 G1 收集器以取代 CMS。
G1 的实现引入了新的概念,旨在实现高吞吐、无内存碎片和可控收集时间等功能。与 CMS 相比,G1具有以下特点:
每个 G1 堆都会划分为多个大小相等的独立区域(Region),这些 Region 可作为新生代的 Eden 空间、Survivor 空间,或老年代空间。每个 Region 都使用了不连续的大小相同的虚拟内存地址,这是与 CMS 的不同之处。G1 的分区类型(HeapRegionType)大致分为四类:新生代分区包括 Eden 和 Survivor;大对象分区则分为大对象头分区和大对象连续分区;以及专门用于存储大对象的 Humongous Heap Region。
G1 的分区类型和分配策略有助于避免内存碎片,提升垃圾回收效率。此外,G1 引入了卡表(Card Table)技术来优化全堆空间扫描,减少 GC 成本。卡表将堆划分为一个个大小为512字节的卡,并维护一个卡表来存储每张卡的一个标识位,表示是否可能存有指向新生代对象的引用。
G1 收集器还采用了 RSet(Remember Set)和 CSet(Collection Set)来优化垃圾收集过程。RSet 记录了其他 Region 对当前持有 Rset Region 中 Card 的引用,使得垃圾收集器无需扫描整个堆即可找到引用。CSet 则收集需要被回收的 Region,在 GC 过程中,存活数据会被移动到另一个可用分区。CSet 占用堆空间的1%大小,减少内存占用。
三色标记法作为工具辅助推导,将遍历对象图过程中遇到的对象标记成三种颜色:白色、灰色和黑色。标记过程分为三步:将 GC Roots 直接引用的对象挪到灰色集合中,从灰色集合获取对象并将其引用的对象挪到灰色集合中,将本对象挪到黑色集合中。重复步骤,直至灰色集合为空。白色集合中仍存在的对象即为 GC Roots 不可达的对象,可以进行回收。标记过程中,当应用程序线程暂停时,对象间引用关系不会改变,便于标记过程。但在并发标记情况下,可能会发生多标或漏标问题,影响 GC 效率和内存回收。
G1 收集器在执行过程中涉及多个阶段,包括初始标记、并发标记、最终标记、存活对象计数和收尾工作。在初始标记阶段,标记由根直接引用的对象。并发标记阶段扫描标记过的对象,标记新创建的对象为存活对象。最终标记阶段扫描 SATB 本地队列中的对象,确保所有引用关系都被正确标记。最后的收尾工作对共享数据进行操作,可能需要暂停应用程序。
G1 收集器提供了两种垃圾收集模式:完全年轻代 GC(Young GC)和部分年轻代 GC(Mixed GC),用于适应不同的应用需求,实现更高效的内存管理和垃圾回收。