Hotspot G1 GC 源码分析

Hotspot G1 GC 源码分析

JDK 版本 openjdk version “19-internal” 2022-09-20

Heap Region 类型

每个 Region 都关联了 Tag:

class HeapRegionType {
    private:
        typedef enum {
            FreeTag               = 0,

            YoungMask             = 2,
            EdenTag               = YoungMask,
            SurvTag               = YoungMask + 1,

            HumongousMask         = 4,
            PinnedMask            = 8,
            StartsHumongousTag    = HumongousMask | PinnedMask,
            ContinuesHumongousTag = HumongousMask | PinnedMask + 1,

            OldMask               = 16,
            OldTag                = OldMask,

            ArchiveMask           = 32,
            OpenArchiveTag        = ArchiveMask | PinnedMask,
            ClosedArchiveTag      = ArchiveMask | PinnedMask + 1
        } Tag;

        volatile Tag _tag;
}

年轻代

G1NewSizePercent 默认值是 5,即年轻代初始默认占用堆的 5% 的大小的空间,G1MaxNewSizePercent 默认值是 60,即年轻代最大默认占用堆的 60% 的大小的空间。

Heap Region

Heap Region 最小不低于 1MB,最大不超过 512 MB,整个堆切分为 2048 个 Region:

class HeapRegionBounds : public AllStatic {
private:
  // Minimum region size; we won't go lower than that.
  // We might want to decrease this in the future, to deal with small
  // heaps a bit more efficiently.
  static const size_t MIN_REGION_SIZE = 1024 * 1024;

  // Maximum region size determined ergonomically.
  static const size_t MAX_ERGONOMICS_SIZE = 32 * 1024 * 1024;
  // Maximum region size; we don't go higher than that. There's a good
  // reason for having an upper bound. We don't want regions to get too
  // large, otherwise cleanup's effectiveness would decrease as there
  // will be fewer opportunities to find totally empty regions after
  // marking.
  static const size_t MAX_REGION_SIZE = 512 * 1024 * 1024;

  // The automatic region size calculation will try to have around this
  // many regions in the heap.
  static const size_t TARGET_REGION_NUMBER = 2048;
}

Heap Region 默认大小的计算方式:

void HeapRegion::setup_heap_region_size(size_t max_heap_size) {
  size_t region_size = G1HeapRegionSize;
  // G1HeapRegionSize = 0 means decide ergonomically.
  if (region_size == 0) {
    region_size = clamp(max_heap_size / HeapRegionBounds::target_number(),
                        HeapRegionBounds::min_size(),
                        HeapRegionBounds::max_ergonomics_size());
  }

  // Make sure region size is a power of 2. Rounding up since this
  // is beneficial in most cases.
  region_size = round_up_power_of_2(region_size);

  // Now make sure that we don't go over or under our limits.
  region_size = clamp(region_size, HeapRegionBounds::min_size(), HeapRegionBounds::max_size());

}

clamp 函数定义在 globalDefinitions.hpp 文件中,如下是定义:

// Return the given value clamped to the range [min ... max]
template<typename T>
inline T clamp(T value, T min, T max) {
  assert(min <= max, "must be");
  return MIN2(MAX2(value, min), max);
}