简单笔记:Java微基准测试工具 jmh一些注意事项

上手参考:https://www.baeldung.com/java-microbenchmark-harness

样例代码参考:http://hg.openjdk.java.net/code-tools/jmh/file/3769055ad883/jmh-samples/src/main/java/org/openjdk/jmh/samples

导包:

<properties>
        <jmh.version>1.27</jmh.version>
</properties>
<dependencies>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>${jmh.version}</version>
        </dependency>
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>${jmh.version}</version>
        </dependency>
</dependencies>

 

主要从 jvm 优化阶段总结几个避坑点:

1.防止 jvm 进行无效代码消除(Dead Code Elimination)

 

public void test0()
{
    int a = 10;
    int b = 9;
    int sum = a + b;
}
 

上面代码没有返回值,且局部变量 sum 没有被用到,这种情况下 jvm 可能直接将此代码判断为无效代码,不去执行它。这是为什么很多规范都要求方法要有返回值的原因,解决方法如下:

public void test(Blackhole blackhole)
{
    ...
    // Consume object. This call provides a side effect preventing JIT to eliminate dependent computations.
    blackhole.consume(sum);
}
 

2.常量折叠(Constant Folding) 带来的基准测试性能偏差

注:常量折叠,一种编译器优化技术,会在编译期间把常量的值计算好(代码中的 a,b,sum),而运行时会直接用编译器算好的结果

 

/**
* 此注解标记一个状态对象,状态对象进入基准测试的方法时,jmh控制状态对象的初始化(避免编译期的常量重叠优化)
*
* Scope.Thread: 状态对象是可共享的,Scope.Thread 指的是共享的范围是单线程(不共享)
* 同列的还有:
* Scope.Group:线程组共享
* Scope.BenchMark:基准测试上下文中的所有 work 线程共享
*/
@org.openjdk.jmh.annotations.State(Scope.Thread)
public static class State
{
public int a = 10;
public int b = 9;
}
​
public void test0(State state,Blackhole blackhole)
{
int a = state.a;
int b = state.b;
int sum = a + b;
blackhole.consume(sum);
}

3.JMH会对 @State 标记的对象进行额外处理,以消除伪共享(False Sharing)

注:伪共享,修改 CPU 缓存行(大小64字节)中的一个变量,会导致该缓存行所有缓存均失效。优化方案是填充变量大小至64字节(独占一个缓存行,不会因为其他变量的写操作,导致自身缓存失效)。 经典的 Disruptor 核心数据结构 RingBuffer 对入队出队索引均作了填充,即是为了消除伪共享。

4.确定方法内敛(Inlining) 对性能的影响,可以考虑打开下面的选项:

​​​​​​​-XX:+PrintInlining

注:内敛,一种编译器优化方案,A 方法内调用 B 方法,若 B 方法为内敛,则编译器会将 B 方法的代码编译进 A 方法,以提高 A 方法的执行速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值