JMH (Java Microbenchmark Harness): The Complete Guide to Microbenchmarking in Java
JMH (Java Microbenchmark Harness) is a library for creating, executing, and analyzing microbenchmarks (performance micro-tests) in Java. Developed by the JVM Performance team (including experts like Alexey Shipilev), JMH is the de facto standard for measuring the performance of small code snippets in the Java ecosystem.
1. What Is JMH and Why Do You Need It?
Writing a correct performance test in Java is a non-trivial task. The JIT compiler, garbage collector, CPU-level optimizations (caching, speculative execution), and even the order of operations can completely skew your results. A simple for loop inside main often leads to the JIT compiler eliminating the tested code as "dead" (Dead Code Elimination), meaning you end up measuring the speed of an empty loop.
JMH solves these problems automatically. It manages code warmup so the JIT compiler stabilizes, prevents dead code elimination, controls forks for JVM isolation, and delivers statistically significant results (mean, percentiles, error margins).
Why do developers need it? To make informed decisions when choosing an algorithm, data structure, serialization method, optimizing a critical code path, or comparing different implementations (e.g., StringBuilder vs String.concat). Without JMH, you risk "optimizing" something that isn't actually a bottleneck, or getting results that don't reproduce in production.
2. Installation
JMH is a Java library, so it's not installed via pip or npm. The most convenient way is to use Maven or Gradle.
Method 1: Maven (Recommended for Quick Start)
Create a new Maven project and add the following to your pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>jmh-example</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jmh</packaging>
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.37</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.37</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Method 2: Gradle
plugins {
id 'java'
id 'me.champeau.jmh' version '0.7.2'
}
dependencies {
implementation 'org.openjdk.jmh:jmh-core:1.37'
annotationProcessor 'org.openjdk.jmh:jmh-generator-annprocess:1.37'
}
jmh {
jmhVersion = '1.37'
}
Method 3: Download JAR (Not Recommended)
You can download a fat-jar from GitHub, but this is less convenient for dependency management.