工具-JMH的使用
参考文献
JMH简介
- JMH,全称 Java Microbenchmark Harness (微基准测试框架),是专门用于Java代码微基准测试的一套测试工具API,是由 OpenJDK/Oracle 官方发布的工具。
基准测试注意点
- 测试前需要预热。
- 防止无用代码进入测试方法中。
- 并发测试。
- 测试结果呈现。
使用场景
- 定量分析某个热点函数的优化效果
- 想定量地知道某个函数需要执行多长时间,以及执行时间和输入变量的相关性
- 对比一个函数的多种实现方式
依赖
1 | <dependency> |
示例
1 |
|
执行测试
- 运行 JMH 基准测试有两种方式,一个是生产jar文件运行,另一个是直接写
main
函数或者放在单元测试中执行.
jar
形式
-
使用
maven-shade-plugin
插件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>jmh-demo</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>-
SpringBoot项目打包报错
Cannot find 'resource' in class org.apache.maven.plugins.shade.resource.ManifestResourceTransformer
-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>jmh-demo</finalName>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.springframework.boot.maven.PropertiesMergingResourceTransformer">
<resource>META-INF/spring.factories</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.openjdk.jmh.Main</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
-
-
执行
mvn clean package
后生成jar
包 -
执行以下命令:
1
java -jar jmh-demo.jar -rf json -rff result.json
-rf json
是输出 json的格式-rff /data/result.json
是输出文件位置和名称
main
形式
1 | /** |
JMH注解
@BenchmarkMode
- 用来配置Mode选项,可用于类或方法上,这个注解的value是一个数组,可以把集中Mode集合在一起执行,还可以设置
Mode.ALL
,即全部执行一遍.
类型 | 描述 |
---|---|
Throughput |
整体吞吐量,每秒执行了多少次调用,单位为opt/time |
AverageTime |
所用平均时间,每次操作的平均耗时,单位为time/op |
SampleTime |
随机取样,最后输出取样结果的分布 |
SingleShotTime |
只运行一次,往往同时把Warmup 次设置为0,用于测试冷启动时的性能 |
All |
所有模式,上面的所有模式都执行一次 |
@State
- 当使用
@Setup
参数的时候,必须在类上加这个参数,不然会提示无法运行。 - 通过 State 可以指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。
@State
可以被继承使用,如果父类定义了该注解,子类则无需定义。由于 JMH 允许多线程同时执行测试 - Scope 主要分为三种。
Thread
: 默认的State,该状态为每个线程独享,每个测试线程分配一个实例。Group
: 同一个组里面所有线程共享。Benchmark
: 所有测试线程间共享一个实例,测试有状态实例在多线程共享下的性能。
@OutputTimeUnit
- 基准测试结果的时间单位。一般选择秒、毫秒、微秒。
@Warmup
-
预热所需要配置的一些基本测试参数,可用于类或者方法上。一般前几次进行程序测试的时候都会比较慢,所以要让程序进行几轮预热,保证测试的准确性。
-
参数含义:
iterations
:预热的次数time
:每次预热的时间timeUnit
:时间的单位,默认秒batchSize
:批处理大小,每次操作调用几次方法
-
@Warmup(iterations = 3)
表示预热轮数
为什么需要预热?
因为 JVM 的 JIT 机制的存在,如果某个函数被调用多次之后,JVM 会尝试将其编译为机器码,从而提高执行速度,所以为了让 benchmark 的结果更加接近真实情况就需要进行预热。
@Measurement
- 实际调用方法所需要配置的一些基本测试参数,可用于类或者方法上,参数和
@Warmup
相同。
@Threads
- 每个进程中的测试线程
@Fork
- 进行 fork 的次数。如果 fork 数是3的话,则 JMH 会 fork 出3个进程来进行测试。
@Benchmark
- 方法级注解,表示该方法是需要进行 benchmark 的对象,用法和 JUnit 的
@Test
类似。
@Param
- 属性级注解,
@Param
可以用来指定某项参数的多种情况。特别适合用来测试一个函数在不同的参数输入的情况下的性能。
@Setup
- 方法级注解,这个注解的作用就是我们需要在测试之前进行一些准备工作 ,比如对一些数据的初始化之类的。
@TearDown
- 方法级注解,这个注解的作用就是我们需要在测试之后进行一些结束工作 ,比如关闭线程池,数据库连接等的,主要用于资源的回收等.
JMH IDEA 插件
JMH 可视化网站
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HoleLin's Blog!