0

0

Java中JMH的作用 解析微基准测试

裘德小鎮的故事

裘德小鎮的故事

发布时间:2025-06-25 12:25:01

|

1069人浏览过

|

来源于php中文网

原创

我们需要使用jmh进行微基准测试,因为传统方法易受jvm优化影响导致结果不准确。1. jmh通过预热、多次迭代等机制规避偏差;2. 提供注解如@benchmark、@setup精细控制测试;3. 使用blackhole防止死代码消除;4. 支持多jvm进程隔离测试干扰;5. 提供参数化测试、状态共享等高级功能;6. 结果包含平均时间、误差范围等指标便于分析。

Java中JMH的作用 解析微基准测试

JMH (Java Microbenchmark Harness) 的作用是帮助开发者编写可靠的微基准测试,从而精确测量Java代码的性能。它解决了传统基准测试中常见的偏差问题,比如JVM预热、代码优化等,为性能优化提供可信的数据支撑。

Java中JMH的作用 解析微基准测试

JMH 是进行精确 Java 性能测试的利器。

Java中JMH的作用 解析微基准测试

为什么我们需要使用 JMH 进行微基准测试?

传统的性能测试方法,比如简单地循环执行代码片段并计算耗时,往往会受到JVM的各种优化措施的影响,导致结果不准确。例如,JIT编译器会根据代码的执行频率进行优化,使得后续的测试结果与首次执行的结果大相径庭。此外,垃圾回收、线程调度等因素也会对测试结果产生干扰。JMH通过一系列精巧的设计,比如预热、多次迭代、防止死代码消除等,有效地规避了这些问题,提供更可靠的性能数据。它就像一个专业的实验室,严格控制各种变量,确保测试结果的准确性。

立即学习Java免费学习笔记(深入)”;

如何使用 JMH 编写一个简单的基准测试?

首先,你需要添加 JMH 的依赖到你的项目中(Maven 或 Gradle)。然后,创建一个类,并使用 JMH 提供的注解来标记你的测试方法。例如,@Benchmark 注解用于标记需要进行基准测试的方法,@State 注解用于定义测试状态,@Setup@TearDown 注解用于在测试前后执行初始化和清理操作。一个简单的例子如下:

Java中JMH的作用 解析微基准测试
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@State(Scope.Thread)
public class MyBenchmark {

    private int[] data;

    @Setup(Level.Trial)
    public void setup() {
        data = new Random().ints(1000).toArray();
    }

    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public void testMethod(Blackhole blackhole) {
        int sum = 0;
        for (int value : data) {
            sum += value;
        }
        blackhole.consume(sum); // 防止死代码消除
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(MyBenchmark.class.getSimpleName())
                .forks(1)
                .warmupIterations(5)
                .measurementIterations(5)
                .build();

        new Runner(opt).run();
    }
}

这个例子展示了如何使用 @Benchmark 标记测试方法,使用 @Setup 进行初始化,并使用 Blackhole 防止死代码消除。main 方法用于配置和运行 JMH 测试。

JMH 中常见的注解及其作用是什么?

JMH 提供了丰富的注解,用于控制基准测试的行为。一些常见的注解包括:

Batch GPT
Batch GPT

使用AI批量处理数据、自动执行任务

下载
  • @Benchmark: 标记一个方法为基准测试方法。
  • @State: 定义测试状态,可以指定状态的作用域(Thread, Group, Benchmark)。
  • @Setup: 在基准测试方法执行之前执行,用于初始化测试数据。可以指定执行级别(Trial, Iteration, Invocation)。
  • @TearDown: 在基准测试方法执行之后执行,用于清理测试数据。同样可以指定执行级别。
  • @BenchmarkMode: 指定基准测试的模式,比如 AverageTime(平均执行时间)、Throughput(吞吐量)、SampleTime(采样时间)等。
  • @OutputTimeUnit: 指定输出结果的时间单位。
  • @Fork: 指定 JVM 进程的数量,用于隔离不同测试之间的影响。
  • @Warmup: 指定预热迭代的次数,让 JVM 充分优化代码。
  • @Measurement: 指定测量迭代的次数,用于收集性能数据。

这些注解允许你精细地控制基准测试的各个方面,从而获得更准确和可靠的性能数据。

如何解读 JMH 的测试结果?

JMH 的测试结果通常包含多个指标,比如平均执行时间、吞吐量、误差范围等。解读这些结果需要一定的经验。首先,关注平均执行时间或吞吐量,这是衡量性能的主要指标。其次,关注误差范围(通常以 ± 符号表示),它表示测试结果的置信区间。如果两个测试结果的误差范围有重叠,则说明它们的性能差异可能不显著。此外,还需要注意测试结果的单位,比如纳秒、微秒、毫秒等。最后,结合具体的业务场景和性能需求,综合分析测试结果,才能得出有意义的结论。例如,如果一个方法的平均执行时间是 100 纳秒 ± 10 纳秒,而另一个方法的平均执行时间是 110 纳秒 ± 5 纳秒,那么可以认为这两个方法的性能差异不大。但如果第一个方法的平均执行时间是 100 纳秒 ± 1 纳秒,而第二个方法的平均执行时间是 110 纳秒 ± 1 纳秒,那么可以认为第二个方法的性能略差。

JMH 如何防止常见的基准测试陷阱?

JMH 通过多种机制来防止常见的基准测试陷阱。

  • 预热(Warmup): 通过多次迭代,让 JVM 充分优化代码,避免冷启动的影响。
  • 死代码消除(Dead Code Elimination): 通过 Blackhole 对象,强制使用测试结果,防止 JIT 编译器优化掉无用的代码。
  • 常量折叠(Constant Folding): 通过动态生成测试数据,避免 JIT 编译器将常量计算提前到编译期。
  • 循环展开(Loop Unrolling): 通过调整循环次数,避免 JIT 编译器过度优化循环。
  • 多 JVM 进程(Fork): 通过创建多个 JVM 进程,隔离不同测试之间的影响,避免相互干扰。

这些机制使得 JMH 能够提供更可靠和准确的性能数据,帮助开发者做出明智的性能优化决策。

除了基本用法,JMH 还有哪些高级特性?

JMH 提供了许多高级特性,可以满足更复杂的性能测试需求。

  • 参数化测试(Parametric Tests): 可以使用 @Param 注解来定义测试参数,JMH 会自动为每个参数值运行一次测试。
  • 状态共享(State Sharing): 可以使用 @State 注解来定义测试状态,并在多个测试方法之间共享状态。
  • 事件监听器(Event Listeners): 可以自定义事件监听器,在测试的不同阶段执行自定义逻辑,比如记录日志、收集统计数据等。
  • 分析器(Profilers): 可以使用 JMH 集成的分析器,比如 perfasmjfr 等,来分析代码的性能瓶颈。
  • 自定义结果处理器(Result Processors): 可以自定义结果处理器,对测试结果进行后处理,比如生成报告、绘制图表等。

这些高级特性使得 JMH 能够应对各种复杂的性能测试场景,帮助开发者深入了解代码的性能特征。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

825

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

728

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.7万人学习

Java 教程
Java 教程

共578课时 | 39.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号