Using JMH for Java Microbenchmarking: Demo, Annotations, and Best Practices
This article introduces Java Microbenchmark Harness (JMH), explains why warm‑up is needed, shows how to build a benchmark project with Maven, provides a complete LinkedList iteration benchmark example with all relevant JMH annotations, demonstrates execution commands, and interprets the resulting performance reports.
In daily Java development, measuring the performance of code fragments is essential, but the JVM’s mixed JIT‑and‑interpreter execution makes raw timing unreliable, so a warm‑up phase is recommended before taking measurements.
JMH (Java Microbenchmark Harness) is the official OpenJDK tool for writing micro‑benchmarks with precision down to microseconds. It provides a set of annotations such as @Benchmark , @BenchmarkMode , @Warmup , @Measurement , @Threads , @Fork , @OutputTimeUnit , @Setup , @TearDown , @State , and @Param to control every aspect of a benchmark.
Project setup
For a quick start you can generate a JMH project with Maven:
$ mvn archetype:generate \
-DinteractiveMode=false \
-DarchetypeGroupId=org.openjdk.jmh \
-DarchetypeArtifactId=jmh-java-benchmark-archetype \
-DgroupId=org.sample \
-DartifactId=test \
-Dversion=1.0Alternatively add the 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>Benchmark example
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.SECONDS)
@Threads(Threads.MAX)
public class LinkedListIterationBenchMark {
private static final int SIZE = 10000;
List
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
From the command line you can build the JAR and execute it:
$ mvn clean install
$ java -jar target/benchmarks.jarOr run it 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();
}The output shows throughput (operations per second) for each benchmark method, e.g.:
Benchmark Mode Cnt Score Error Units
LinkedListIterationBenchMark.forEachIterate thrpt 2 1192.380 ops/s
LinkedListIterationBenchMark.forIndexIterate thrpt 2 206.866 ops/sAnnotation details
@BenchmarkMode – selects the measurement type (Throughput, AverageTime, etc.).
@Warmup – number of warm‑up iterations before real measurement.
@Measurement – number of measurement iterations and their duration.
@Threads – how many threads run the benchmark concurrently.
@Fork – how many separate JVM forks are used.
@OutputTimeUnit – unit for reporting results.
@Setup / @TearDown – code executed before/after each benchmark iteration.
@State – defines the scope of shared state (Thread, Group, Benchmark).
@Param – supplies multiple values for a field to test different inputs.
JMH can be applied to benchmark logging frameworks, bean‑copy utilities, or any Java component where precise performance data is required.
For more examples, refer to the official JMH samples repository:
https://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.