JMH简介
JMH 是 OpenJDK 团队开发的一款基准测试工具,一般用于代码的性能调优,精度甚至可以达到纳秒级别,适用于 java 以及其他基于 JVM 的语言。和 Apache JMeter 不同,JMH 测试的对象可以是任一方法,颗粒度更小,而不仅限于rest api。
JMH 比较典型的应用场景如下:
- 想准确地知道某个方法需要执行多长时间,以及执行时间和输入之间的相关性
- 对比接口不同实现在给定条件下的吞吐量
- 查看多少百分比的请求在多长时间内完成
JMH基础及常用注解说明
JMH主要是通过注解的形式编写测试单元,告诉JMH如何测试,JMH自动生成测试代码,所以在使用JMH进行微基准测试时一定要先了对JMH注解有一定了解,下面就介绍下JMH的注解。
@Benchmark
@Benchmark用于告诉JMH哪些方法需要进行测试,只能注解在方法上,有点类似junit的@Test。在测试项目进行package时,JMH会针对注解了@Benchmark的方法生成Benchmark方法代码。通常情况下,每个Benchmark方法都运行在独立的进程中,互不干涉。
@BenchmarkMode
@BenchmarkMode用于指定当前Benchmark方法使用哪种模式测试。JMH提供了4种不同的模式,用于输出不同的结果指标,如下:
- Throughput:吞吐量,ops/time。单位时间内执行操作的平均次数
- AverageTime:每次操作所需时间,time/op。执行每次操作所需的平均时间
- SampleTime:同 AverageTime,区别在于 SampleTime会随机取样,最后输出取样结果的分布
- SingleShotTime:同 AverageTime。区别在于 SingleShotTime 只执行一次操作。这种模式的结果存在较大随机性。
- All:上边所有的都执行一遍
@BenchmarkMode支持数组,可以指定多种模式也可以配置All,所有模式都执行一遍
@Warmup和@Measurement
@Warmup和@Measurement分别用于配置预热迭代和测试迭代。其中,iterations用于指定迭代次数,time和timeUnit用于每个迭代的时间,batchSize表示执行多少次Benchmark方法为一个invocation。
@State
通过 State 可以指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。@State 可以被继承使用,如果父类定义了该注解,子类则无需定义。由于 JMH 允许多线程同时执行测试,不同的选项含义如下:
- Scope.Benchmark:所有测试线程共享一个实例,测试有状态实例在多线程共享下的性能
- Scope.Group:同一个线程在同一个 group 里共享实例
- Scope.Thread:默认的 State,每个测试线程分配一个实例
@Setup 和 @TearDown
这两个注解只能定义在注解了 State 里,其中,@Setup类似于 junit 的@Before,而@TearDown类似于 junit 的@After。
@State(Scope.Thread)
public class JMHSample_05_StateFixtures {
double x;
@Setup(Level.Iteration)
public void prepare() {
System.err.println("init............");
x = Math.PI;
}
@TearDown(Level.Iteration)
public void check() {
System.err.println("destroy............");
assert x > Math.PI : "Nothing changed?";
}
@Benchmark
public void meas

JMH是一款由OpenJDK团队开发的高精度基准测试工具,适用于Java和JVM语言。本文详细介绍了JMH的基础知识,包括@Benchmark、@BenchmarkMode、@Warmup、@Measurement等关键注解的用法,以及如何避免性能测试中的陷阱。同时,展示了如何在IDEA中使用JMH插件进行便捷测试,并给出了Maven集成和执行的示例。此外,还提到了JMH测试结果的可视化工具。
最低0.47元/天 解锁文章
542

被折叠的 条评论
为什么被折叠?



