bigywater.tech
Java · 209

Epsilon GC:只分配不回收有什么用

Epsilon GC 只分配不回收,到底有什么用?这篇验证它堆满时的行为、短任务里的速度,以及作为「没有屏障」的基线测量引用存储(其它回收器的行为见前面的篇目)。

退出码 3
Epsilon 堆满后 JVM 的退出方式,OutOfMemoryError 不可捕获
161 vs 92 ms
Epsilon 与 Serial 在 915 MB 短命对象分配循环里的耗时
0.346 vs 1.473 ns
Epsilon 与 G1 的引用存储耗时

堆满时的行为

实测 · 本机执行输出
  JVM 输出(去掉时间戳后的前几行):
    [info][gc] Using Epsilon
    [info][gc] Consider enabling -XX:+AlwaysPreTouch to avoid memory commit hiccups
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 14248K (5.44%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 29939K (11.42%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 43588K (16.63%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 59972K (22.88%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 76356K (29.13%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 92740K (35.38%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 106M (41.63%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 122M (47.88%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 138M (54.13%) used
    [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 154M (60.38%) used
  程序捕获到:
  JVM 退出码 = 3;GC 日志里 Pause 的行数 = 0

分配速度

实测 · 本机执行输出
回收器                   耗时        GC 日志里的 Pause 次数
Epsilon           161 ms                       0
Serial             92 ms                       3
Parallel           87 ms                       3
G1                126 ms                       3

  (如果堆只有 256 MB,总分配量超过堆时 Epsilon 的结果:)
  退出码 3;输出末尾:[info][gc] Heap: 256M reserved, 256M (100.00%) committed, 234M (91.65%) used | [info][gc] Heap: 256M reserved, 256M (100.00%) committed, 250M (97.90%) used | Terminating due to java.lang.OutOfMemoryError: Java heap space

没有屏障

实测 · 本机执行输出
  Epsilon   引用存储 0.346 ns/次
  Serial    引用存储 0.418 ns/次
  G1        引用存储 1.473 ns/次

分步演示

Epsilon GC
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12,macOS,堆 256m / 1g;Epsilon 是实验性选项(-XX:+UnlockExperimentalVMOptions)
    • 没有验证:Epsilon 比 Serial 慢的原因(没有看页错误次数,-XX:+AlwaysPreTouch 的影响也没有测)、-XX:EpsilonMaxTLABSize 等参数、Epsilon 在 JMH 基线中的使用、JDK 17 与 27 的差异、-XX:+HeapDumpOnOutOfMemoryError 在 Epsilon 下的行为;耗时取 3 次最好
    京ICP备2026067502号-1京公网安备11010502063487号