垃圾收集器接口

doMore 523 2022-07-27

概要

通过引入一个干净的垃圾收集器接口,加大不同垃圾收集器源代码的隔离力度。

目的

  • 内部 GC 代码更好的模块化
  • 向 HotSpot 添加一个新的 GC 更简单,而且不会干扰当前的代码库
  • JDK 删除 GC 更容易

动机

每个垃圾收集器实现都在 src/hotspot/share/gc/$NAME 目录的源文件,例如 G1 在 src/hotspot/share/gc/g1 中,CMS 在 src/hotspot/share/gc/cms 等。但是,在 HotSpot 源中散落着点点滴滴。例如,大多数 GC 需要一定的屏障,需要在运行时、解释器、C1 和 C2 中实现。这些屏障不在 GC 特定的目录中,而是在 shared interpreter、C1 和 C2 源代码中(通常是 大量的 if-else 链)。同样的问题适用于 例如 MemoryMXBeans 等 诊断代码。这种源代码布局有以下几个缺点:

  1. 对于 GC 开发人员来说,实现一个新的垃圾收集器需要了解所有这些不同的地方,以及如何扩展他们以满足他们的特定需求
  2. 对于不是 GC 开发人员的 HotSpot 开发人员来说,在哪里可以找到特定 GC 的特定代码段时令人困惑。
  3. 在构建时很难排除特定的垃圾收集器。#define INCLUDE_ALL_GCS 长期以来一直是一中仅使用内置串行收集器构建 JVM 的方法,但是这种机制变得太不灵活。

更干净的 GC 接口将会使实现新的收集器变得更加容易,它会使代码更加干净,并且在构建时排除一个或多个垃圾收集器更简单。添加新的垃圾收集器应该是实现一组有据可查的接口,而不是找出 HotSpot 中所有需要更改的地方。

描述

GC 接口将定义已存在类 CollectedHeap ,并且每个垃圾收集器都必须实现。CollectedHeap 类将驱动垃圾收集器和 HotSpot 的交互。具体地说,垃圾收集器实现必须提供:

  • 一个 CollectedHeap 的子类
  • 屏障集,BarrierSet 的子类,实现运行时各种屏障的 CollectorPolicy 的实现
  • GCInterpreterSupport 的实现,它为 解释器 实现了 GC 的各种屏障(使用汇编指令)
  • GCC1Support 的实现,为 C1 编译器的 GC 实现了各种屏障
  • GCC2Support 的实现,为 C2 编译器的 GC 实现了各种屏障
  • GC 特定参数的最终初始化
  • 设置 MemoryService ,相关内存池,内存管理器等。

在多个垃圾收集器之间共享实现细节的代码应该存在于帮助器类中。这样它就可以很容易的被不同的 GC 实现所使用。例如:可能有一个帮助器类实现了 卡表 (card table)支持的各种屏障,并且任何需要卡表后屏障的 GC 都将可以调用该帮助器类的相应方法。通过这种方式,接口提供了实现全新屏障的灵活性,允许同时以混合搭配的方式重用现有代码。