JVM-G1垃圾回收器

48 阅读2分钟

G1和传统分代收集器(如 Parallel、CMS)对比

1.内存空间差异

G1 回收器仍然有 Eden、Survivor 和 Old 代的概念,但是它们的实现方式和传统的分代收集器有本质区别

传统分代收集器(如 Parallel、CMS):

text

+----------------------+
|       Young Gen      |
|  +------+----------+ |
|  | Eden | Survivor | |
|  +------+----------+ |
+----------------------+
|       Old Gen        |
+----------------------+
  • 连续内存区域:年轻代和老年代是连续的物理内存块
  • 固定比例:通过 -XX:NewRatio-XX:SurvivorRatio 固定比例

G1 收集器:

text

+-----------------------------------+
| Region 0 | Region 1 | Region 2 | ... | Region N |
+-----------------------------------+
|   Eden   | Survivor |   Old    | Humongous | ... |
+-----------------------------------+
  • Region 分区:堆被划分为多个大小相等的 Region(通常 1MB-32MB)
  • 动态角色:每个 Region 可以动态充当 Eden、Survivor、Old 或 Humongous 区域
  • 逻辑分代:Eden、Survivor、Old 是逻辑概念,物理上分散在不同的 Region 中

G1 回收器确实有 Young GC 和 Full GC,但它们的实现方式与传统收集器有所不同

2. G1 的 GC 类型

Young GC(年轻代垃圾回收)

触发条件:当 Eden Region 被填满时触发

执行过程

  • STW(Stop-The-World) :应用线程暂停
  • 拷贝存活对象:将 Eden Region 和 Survivor Region 中的存活对象拷贝到新的 Survivor Region
  • 年龄计数:对象年龄增加,达到阈值(默认15)的对象晋升到 Old Region
  • Region 角色转换:原来的 Eden Region 变为空闲 Region

GC 日志示例

text

[GC pause (G1 Evacuation Pause) (young)
  [Eden: 100.0M(100.0M)->0.0B(1024.0K) 
   Survivors: 1024.0K->2048.0K 
   Heap: 100.0M(128.0M)->2048.0K(128.0M)]

Mixed GC(混合垃圾回收)

触发条件:当堆占用率达到 -XX:InitiatingHeapOccupancyPercent 阈值(默认45%)时,在并发标记周期后触发

执行过程

  • STW:应用线程暂停
  • 同时回收:回收年轻代 Region + 部分老年代 Region(选择垃圾最多的 Region 优先回收)
  • Garbage-First:基于 Region 的回收价值(垃圾比例)来决定回收顺序

GC 日志示例

text

[GC pause (G1 Evacuation Pause) (mixed)
  [Eden: 1024.0K(1024.0K)->0.0B(1024.0K) 
   Survivors: 2048.0K->1024.0K 
   Heap: 120.0M(128.0M)->80.0M(128.0M)]

Full GC(全局垃圾回收)

触发条件(G1 的设计目标就是尽量避免 Full GC!):

  • 并发模式失败:回收速度跟不上分配速度
  • 晋升失败:Young GC 时老年代没有足够空间接收晋升对象
  • 大对象分配失败:无法找到连续的 Humongous Region
  • 系统显式调用System.gc()(除非使用 -XX:+ExplicitGCInvokesConcurrent
回收方式区域触发条件
Young GC(年轻代)Eden Region Survivor RegionEden Region 被填满时触发
Mixed GC(混合)回收年轻代 Region + 部分老年代 Region堆占用率达阈值
Full GC(全局)老年代 Region 和 Humongous Region老年代没有足够空间 无法找到连续的 Humongous Region