Java 性能调优实战:JMH 基准测试与 JProfiler/Async-Profiler 剖析
在 Java 性能调优中,最大的误区往往是'凭感觉优化'。很多开发者习惯用 System.currentTimeMillis() 简单测量耗时,但这在 JVM 环境下极不可靠。
// 反例:手工测量的不准确基准测试
long start = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
// 被测试代码
}
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
这种写法的问题很明显:它忽略了 JIT 编译优化、GC 干扰以及系统负载波动。单次运行结果缺乏统计学意义,很容易得出错误结论。专业的性能工程需要科学的基准测试配合精准的性能剖析。
JMH:Java 微基准测试工具
JMH 简介与设计哲学
JMH(Java Microbenchmark Harness)是 Oracle 专门用于编写、运行和分析 Java 微基准测试的工具。它的核心设计目标就是解决 JVM 特性带来的测试挑战,比如死代码消除、循环优化以及 JIT 预热效应。通过强制预热和多次迭代统计,JMH 能提供可靠的性能数据。
JMH 核心概念与注解详解
JMH 采用注解驱动的方式配置测试,理解这些注解对写出正确的测试至关重要。
@BenchmarkMode(Mode.AverageTime) // 测试模式:平均时间
@OutputTimeUnit(TimeUnit.NANOSECONDS) // 输出时间单位
@Warmup(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) // 预热设置
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) // 正式测量
@Fork(2) // fork 进程数,隔离 GC 影响
@State(Scope.Thread) // 测试状态作用域
public class MyBenchmark {
private List<String> testData;
@Setup
{
testData = <>();
( ; i < ; i++) {
testData.add( + i);
}
}
{
(String str : testData) {
blackhole.consume(str.length());
}
}
{
testData.stream()
.mapToInt(String::length)
.forEach(blackhole::consume);
}
}





