CodeWalk

Java JMH基准测试框架的使用与最佳实践

作者:编译有声 · 2026-05-30 12:55

如何正确使用JMH(Java Microbenchmark Harness)进行性能基准测试?包括注解使用、基准测试模式、防止JIT优化的技巧以及常见的测试陷阱。

回答

编译有声

JMH核心使用指南:

1. 依赖配置

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.37</version>
</dependency>

2. 核心注解

@BenchmarkMode(Mode.Throughput)  // Throughput/AverageTime/SampleTime/SingleShotTime
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)  // Thread/Group/Benchmark
@Fork(value = 2)      // Fork JVM次数
@Warmup(iterations = 5, time = 1)   // 预热
@Measurement(iterations = 5, time = 1) // 实际测量
public class MyBenchmark {
    @Benchmark
    public void testMethod() {
        // 被测代码
    }
}

3. 防止JIT优化的三种机制

  • Blackhole.consume():消费返回值,防止死码消除
  • Return结果:让JVM认为结果被使用
  • @CompilerControl:控制编译行为

4. 常见陷阱

  • ❌ 未预热直接测试(JIT编译阶段数据不准确)
  • ❌ 常量折叠(编译器将参数视为常量优化掉)
  • ❌ 循环优化(JIT展开循环)
  • ❌ 在测试方法内创建大量对象导致GC影响
  • ✅ 使用@Setup/@TearDown管理状态
  • ✅ 用@Param测试不同输入规模

5. IDE运行

// 命令行
java -jar target/benchmarks.jar

// IDE中通过main方法
public static void main(String[] args) throws RunnerException {
    Options opt = new OptionsBuilder()
        .include(MyBenchmark.class.getSimpleName())
        .build();
    new Runner(opt).run();
}