- 1.JMH简介
- 1.1 JMH概念
- 1.2 JMH与JMeter区别
- 1.3 JMH注解说明
- 2.JMH使用
- 2.1 创建项目
- 2.2 引入依赖
- 2.3 启动异常解决
- 2.4 JMH案例1
JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targetting the JVM.
JMH是一种Java工具,用于构建、运行和分析用Java和其他针对JVM的语言编写的nano/micro/mili/macro基准测试。
JMH 是 OpenJDK 团队开发的一款基准测试工具,一般用于代码的性能调优,精度甚至可以达到纳秒级别,适用于 java 以及其他基于 JVM 的语言。和 Apache JMeter 不同,JMH 测试的对象可以是任一方法,颗粒度更小,而不仅限于rest api。
官方地址:http://openjdk.java.net/projects/code-tools/jmh/
官网案例:http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
JMeter更多是对rest api接口进行压测,可以通过设置参数编写脚本实现模拟并发场景进行单模块或者是整个链路进行压测。
而JMH关注的是某一段代码或者是某个方法在jvm中执行的效率,颗粒度更细,可以使用 JMH 对优化的效果进行定量的分析。
在运行时,注解配置被用于解析生成BenchmarkListEntry配置类实例。
一个方法对应一个@Benchmark注解,一个@Benchmark注解对应一个基准测试方法。
注释在类上的注解,或者注释在类的字段上的注解,则是类中所有基准测试方法共用的配置。
@Benchmark声明一个public方法为基准测试方法。
@BenchmarkMode通过JMH我们可以轻松的测试出某个接口的吞吐量、平均执行时间等指标的数据(假设我想测试testGson方法的平均耗时,那么可以使用@BenchmarkMode注解指定测试维度为Mode.AverageTime。)
@Measurement测量次数
@Measurement假设我想测量testGson方法五次,那么可以使用@Measurement注解。
@Warmup配置预热参数。
为了数据准确,我们可能需要让testGson方法做下热身运动。如在方法中创建GsonParser对象,预热可以避免首次创建GsonParser时因多了类加载的耗时而导致测试结果不准备的情况。jvm使用JIT即时编译器,一定的预热次数可让JIT对testGson方法的调用链路完成编译,去掉解释执行对测试结果的影响。
@OutputTimeUnit
OutputTimeUnit注解用于指定输出的方法执行耗时的单位。如果方法执行耗时为秒级别,为了便于 观察结果,我们可以使用@OutputTimeUnit指定输出的耗时时间单位为秒;如果方法执行耗时为毫秒级别,为了便于观察结果,我们可以使用@OutputTimeUnit指定输出的耗时时间单位为毫秒,否则使用默认的秒做单位,会输出10的负几次方这样的数字,不太直观。
@Fork用于指定fork出多少个子进程来执行同一基准测试方法。假设我们不需要多个进程,那么 可以使用@Fork指定为进程数为1。
@Threads注解用于指定使用多少个线程来执行基准测试方法,如果使用@Threads指定线程数为2,那么每次测量都会创建两个线程来执行基准测试方法。
2.JMH使用 2.1 创建项目创建一个基准测试项目,基本的Maven项目引入jmh依赖,jmh包括两部分jmh-core与jmh-generator-annprocess。
2.2 引入依赖2.3 启动异常解决org.openjdk.jmh jmh-core 1.33 org.openjdk.jmh jmh-generator-annprocess 1.33 provided
关于JMH运行ERROR: transport error 202: connect failed: Connection refused ERROR解决。
网上有很多说法,又是插件引入,又是idea配置,实际上你应该是启动的debug模式,换成run模式就行。
public class JMHSample_01_HelloWorld {
@Benchmark
@BenchmarkMode(Mode.Throughput)
@Warmup(iterations = 3)
@Measurement(iterations = 3, time = 5, timeUnit = TimeUnit.SECONDS)
@Threads(1)
@Fork(1)
@OutputTimeUnit(TimeUnit.SECONDS)
public void wellHelloThere() throws InterruptedException {
Thread.sleep( 1000 );
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include( JMHSample_01_HelloWorld.class.getSimpleName() )
.forks( 1 )
.build();
new Runner( opt ).run();
}
}



