G1的内存划分

122 阅读3分钟

G1的内存划分

G1 是 JDK 7u4 引入的服务器级垃圾收集器,其内存划分与传统分代收集器有本质不同。以下是 G1 内存结构的完整解析:

内存分区结构

graph TD
    A[G1 堆内存] --> B[等大Region] 
    A --> C[大对象Region]
    
    B --> B1[默认大小: 1MB-32MB]
    B --> B2[可调参数: -XX:G1HeapRegionSize]
    
    C --> C1[最小单位: 1个Region]
    C --> C2[可扩展: 多Region连续存储]
    C --> C3[触发条件: >50% RegionSize]
    
style B2 white-space:normal
graph TD
    A[G1 内存结构] --> B[逻辑分代]
    A --> C[物理分区]

    B --> B1[年轻代 Young Generation]
    B --> B2[老年代 Old Generation]
    B --> B3[大对象区 Humongous]

    C --> C1[固定大小Region]
    C1 --> D[Eden Regions]
    C1 --> E[Survivor Regions]
    C1 --> F[Old Regions]
    C1 --> G[Humongous Regions]
    C1 --> H[空闲Region]

一、G1 的分代模型(逻辑分代)

1. 与传统分代收集器的对比

特性传统分代收集器G1 收集器核心差异
内存隔离严格物理隔离年轻代与老年代有固定边界逻辑分代无物理隔离G1 取消物理隔离,实现动态区域分配
内存布局连续内存块各代占据连续地址空间分区模型堆划分为等大小 RegionG1 的 Region 分区避免内存碎片
比例控制固定比例通过 -Xmn/-XX:NewRatio 等参数静态设置动态调整运行时根据 GC 效率自动调节各代占比G1 实现运行时自适应优化
大对象处理存储在老年代可能导致内存碎片专用 Humongous Region全局列表管理G1 隔离大对象避免影响常规对象
回收单位整个分代Young GC 处理整个年轻代单个 Region可选择高收益 Region 优先回收G1 实现更精准的回收控制

2. 逻辑分代的实现

G1的内存都是Region,所以新生代和老年代只是分布在不同的Region

graph LR
    年轻代 --> 区域[Eden/Survivor Region]
    老年代 --> 区域[Old Region]
    大对象 --> 区域[Region]

    G1控制器 --> 监控[监控GC效率]
    监控 --> 调整[动态调整区域分配]

二、Region 分区设计(物理实现)

1. Region 的核心特性

classDiagram
    class Region {
        +大小:1MB~32MB(默认堆大小/2048)
        +类型:Eden/Survivor/Old/Humongous
        +标记:存活对象信息
        +RSet:记录引用关系
    }

2. 等大 Region(固定大小分区)

特性说明
默认大小1MB-32MB,根据堆大小自动计算
计算公式RegionSize = HeapSize ÷ 2048
大小约束1MB ≤ RegionSize ≤ 32MB
内存对齐始终为 2 的幂 (1, 2, 4, 8, 16, 32MB)

3. Region 类型与功能

Region 类型存储对象回收策略
Eden Region新创建的小对象只被 Young GC 回收
Survivor Region年轻代存活对象Young GC 后晋升
Old Region老年代对象Mixed GC 回收
Humongous Region大对象(>50% RegionSize)直接老年代回收
空闲 Region未分配可转为任意类型

三、对象存储策略

1. 小对象分配(≤50% RegionSize)

sequenceDiagram
    应用线程 ->> TLAB: 线程本地分配缓冲区
    TLAB ->> Eden Region: 分配小对象
    alt TLAB空间不足
        Eden Region-->>新Region: 申请新Region
        新Region-->>TLAB: 提供新空间
    end

2. 大对象分配(>50% RegionSize)

flowchart TD
    大对象请求 --> 判断{是否>单个Region?}
    判断 -->|是| 连续分配[分配连续Region]
    判断 -->|否| 单Region[分配单个Region]

    连续分配 --> 标记[起始Region标记H-start]
    连续分配 --> 后续[后续Region标记H-cont]

    全局记录 --> 列表[加入全局大对象列表]

四、内存管理关键机制

1. 动态区域调整

gantt
    title G1 区域动态调整示例
    dateFormat  GC
    axisFormat  %s

    section 初始状态
    Eden : des1, 0, 40
    Survivor : des2, 0, 10
    Old : des3, 0, 50

    section Young GC后
    Eden重置 : 40, 30
    Survivor晋升 : 45, 5
    Old增加 : 50, 5

    section Mixed GC后
    Old回收 : 55, -15

2. 巨型对象特殊处理

image.png

# 大对象阈值(默认50% RegionSize)
-XX:G1HeapWastePercent=10  # 允许浪费空间比例
-XX:G1MixedGCLiveThresholdPercent=65 # 混合GC存活对象阈值

五、技术总结

G1 内存设计的三大突破:

mindmap
  root((G1内存设计优势))
    分区模型
      固定大小Region
      消除内存碎片
      并行回收基础
    逻辑分代
      保持分代优势
      动态调整比例
      优化回收策略
    巨型对象处理
      专用Humongous区
      全局列表管理
      特殊回收策略

​关键结论​​:

  1. G1 采用 逻辑分代+物理分区 的创新模型:
    • 逻辑分代:保留年轻代(Young)、老年代(Old)、大对象(Humongous)概念
    • 物理分区:堆划分为固定大小(1-32MB)的 Region
  2. 对象存储策略
    • 小对象(≤50% Region):存储在 Eden Region
    • 普通对象:晋升到 Old Region
    • 大对象(>50% Region):直接分配到 Humongous Region
  3. 动态调节:运行时根据GC效率动态调整各代Region比例,避免了分代之间空间分配不合理的问题。