Master Java Performance Testing with JMH: A Complete Guide and Demo
This article explains why measuring Java code performance is essential, introduces the JMH microbenchmark framework, details its key annotations and configuration options, and provides step‑by‑step instructions and code examples for building, writing, and running benchmarks to obtain reliable results.
Introduction
Accurate performance measurement is crucial for Java development because the JVM mixes interpreted and JIT‑compiled execution, making it hard to determine stable test results without proper warm‑up.
If you cannot measure it, you cannot improve it.
JMH (Java Microbenchmark Harness) is an official OpenJDK tool designed for micro‑benchmarking at the method level with microsecond precision.
Key Points for Java Benchmarking
Warm up the code before measuring.
Avoid dead code elimination in benchmark methods.
Use concurrent testing when appropriate.
Present results clearly.
When to Use JMH
Quantitatively analyze the effect of optimizing a hotspot function.
Determine execution time and its relation to input variables.
Compare multiple implementations of a function.
Demo Project Setup
JMH works with Java 9+; the example uses Java 8.
Build a Maven project with the JMH archetype:
$ mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=test \
-Dversion=1.0Alternatively, add the following dependencies to an existing Maven project:
<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>
<scope>provided</scope>
</dependency>Writing a Benchmark
The example compares LinkedList iteration via index versus foreach:
/**
* @author Richard_yyf
* @version 1.0 2019/8/27
*/
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.SECONDS)
@Threads(Threads.MAX)
public class LinkedListIterationBenchMark {
private static final int SIZE = 10000;
private List<String> list = new LinkedList<>();
@Setup
public void setUp() {
for (int i = 0; i < SIZE; i++) {
list.add(String.valueOf(i));
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void forIndexIterate() {
for (int i = 0; i < list.size(); i++) {
list.get(i);
System.out.print("");
}
}
@Benchmark
@BenchmarkMode(Mode.Throughput)
public void forEachIterate() {
for (String s : list) {
System.out.print("");
}
}
}Running the Benchmark
Execute via generated JAR:
$ mvn clean install
$ java -jar target/benchmarks.jarOr run directly from a main method:
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(LinkedListIterationBenchMark.class.getSimpleName())
.forks(1)
.warmupIterations(2)
.measurementIterations(2)
.output("E:/Benchmark.log")
.build();
new Runner(opt).run();
}Result Example
Benchmark Mode Cnt Score Error Units
LinkedListIterationBenchMark.forEachIterate thrpt 2 1192.380 ops/s
LinkedListIterationBenchMark.forIndexIterate thrpt 2 206.866 ops/sAnnotation Overview
Key JMH annotations:
@BenchmarkMode : Defines benchmark mode (Throughput, AverageTime, SampleTime, SingleShotTime, All).
@Warmup : Number of warm‑up iterations.
@Measurement : Number of measurement iterations, time, and time unit.
@Threads : Number of threads used.
@Fork : Number of JVM forks.
@OutputTimeUnit : Unit for reporting results.
@Benchmark : Marks a method as a benchmark.
@Param : Supplies multiple values for a field.
@Setup and @TearDown : Prepare and clean up resources.
@State : Declares a class as shared state with a defined scope (Thread, Group, Benchmark).
Conclusion
JMH enables reliable micro‑benchmarking of Java code, allowing developers to evaluate optimizations, compare implementations, and understand performance characteristics. For more examples, refer to the official JMH samples repository.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
