bigywater.tech
Java · 308

JMH Blackhole:如何保留基准中的计算结果

基准里的结果要交给 Blackhole 才不会被优化掉。但 Blackhole 自己有多贵?不同模式差多少?丢弃结果时它还能救你吗?这篇用同一组基准在三种模式下逐个量出来。

3 种
Blackhole 模式:compiler、full、full + dont-inline hint
0.590 / 1.106 / 1.929 ns
同一个 sqrt 在三种模式下的 JMH 结果
1705 ns
Blackhole.consumeCPU(1000) 的耗时(约 1.7 ns/token)

Blackhole 模式对比

实测 · 本机执行输出
  模式 (自动检测,默认):['# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)']
  模式 COMPILER:['# Blackhole mode: compiler (forced)']
  模式 FULL:['# Blackhole mode: full (forced)']
  模式 FULL_DONTINLINE:['# Blackhole mode: full + dont-inline hint (forced)']
  基准                                     (自动检测,默认)          COMPILER              FULL   FULL_DONTINLINE
  r0_empty                                   0.314             0.350             0.313             0.353
  r1_returnSqrt                              0.590             0.590             1.106             1.929
  r2_bhConsumeSqrt                           0.591             0.590             1.107             1.928
  r3_discardSqrt                             0.313             0.313             0.313             0.313
  r4_twoComputed_returnOne                   4.808             4.785             4.935             5.962
  r5_twoComputed_consumeBoth                 4.797             4.786             5.361             8.266
  r6_twoComputed_returnSum                   7.057             8.020             5.337             6.321
  r7_consumeConstant                         0.313             0.314             0.563             1.971
  r8_consumeCPU_1                            2.291             2.291             2.289             2.290
  r9_consumeCPU_10                           6.411             6.433             6.412             6.446
  r9_consumeCPU_100                        140.738           140.659           140.400           140.677
  r9_consumeCPU_1000                      1705.166          1708.197          1701.094          1704.264
  (单位 ns/op)

分步演示

JMH Blackhole
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK(Temurin 17.0.20、Homebrew 21.0.12 与 27,每篇注明实际用的版本);用 javac 编译、java 直接运行,需要第三方库时用 Maven 解析依赖;计时用 System.nanoTime,数字每次运行会有小幅抖动。JDK 21.0.12,JMH 1.37,Apple Silicon;2 次预热 + 3 次测量各 1 秒,1 个 fork,模式用 -Djmh.blackhole.mode 强制
    • 没有验证:JDK 27 上的 Blackhole 行为、r6 波动(5.3–8.0 ns/op)的原因、Math.log 没有被消除的原因、多线程下 Blackhole 的争用、-prof perfasm 看生成的代码
    京ICP备2026067502号-1京公网安备11010502063487号