0Pricing
Java Academy · Lektion

Warum JMH

Naive Fehler bei Benchmarks vermeiden

Warum JMH ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum JMH

Der Java Microbenchmark Harness (JMH) ist das Standardwerkzeug zum Messen der Leistung kleiner Java-Codeabschnitte. Selbst geschriebene Zeitmessschleifen liefern fast immer falsche Werte, weil die JVM eine hochentwickelte Laufzeitumgebung mit Optimierungen ist.

JMH wurde entwickelt, um diese Stolperfallen zu neutralisieren.

Der naive Benchmark

Ein typischer erster Versuch besteht darin, eine Schleife in System.nanoTime() einzuschließen. Das wirkt plausibel, ist für Microbenchmarks jedoch grundlegend fehlerhaft.

public class Main {
    static int compute(int n) { return n * n + 7; }
    public static void main(String[] args) {
        long start = System.nanoTime();
        int sink = 0;
        for (int i = 0; i < 1_000_000; i++) sink = compute(i);
        long elapsed = System.nanoTime() - start;
        System.out.println("ns: " + elapsed + " sink=" + sink);
    }
}

Problem 1: JIT-Warmup

Die JVM startet im interpretierten Modus und kompiliert häufig ausgeführte Methoden erst nach Tausenden von Aufrufen in nativen Code. Ein naiver Benchmark misst die langsame interpretierte Phase zusammen mit der schnellen kompilierten Phase und liefert dadurch bedeutungslose Durchschnittswerte.

JMH löst dieses Problem mit einer eigenen Warmup-Phase, deren Ergebnisse verworfen werden.

Problem 2: Dead-Code-Eliminierung

Wenn ein berechnetes Ergebnis nie verwendet wird, kann der JIT die Berechnung vollständig entfernen. Ihr Benchmark misst dann eine leere Schleife.

JMH stellt die Verwendung von Rückgabewerten und den Blackhole bereit, um dies zu verhindern.

Problem 3: Constant Folding

Wenn Eingaben Compilezeitkonstanten sind, berechnet der JIT das Ergebnis einmal und verwendet es wieder. Im folgenden Beispiel könnte der Compiler die gesamte Schleife durch eine einzige Konstante ersetzen.

JMH verwendet @State-Objekte, sodass die Eingaben für den Optimierer undurchsichtig sind.

public class Main {
    public static void main(String[] args) {
        // 2 * 21 is constant; the JIT folds it to 42
        int result = 2 * 21;
        System.out.println(result);
    }
}

Problem 4: Schleifenoptimierungen

Der JIT entrollt Schleifen, zieht invarianten Code aus Schleifen heraus und vektorisiert Operationen. Eine von Hand geschriebene Schleife misst dadurch diese Optimierungen statt der Operation, die Sie eigentlich testen wollten.

JMH ersetzt Ihre Schleife durch sorgfältig kontrollierte Iterationszahlen, die es selbst verwaltet.

Problem 5: On-Stack-Replacement

Eine lang laufende Schleife in main kann während der Ausführung kompiliert werden (On-Stack-Replacement). Dadurch entstehen andere Leistungsmerkmale als bei einer normal kompilierten Methode. Das verfälscht die Ergebnisse auf unvorhersehbare Weise.

Was JMH bereitstellt

  • Separate, verworfene Warmup-Iterationen.
  • Mehrere Messiterationen mit statistischen Auswertungen.
  • Ausführung in neuen JVMs, um eine Verfälschung durch zuvor erstellte Profile zu vermeiden.
  • Blackhole und die Verwendung von Ergebnissen zum Verhindern der Dead-Code-Eliminierung.
  • @State-Objekte zum Verhindern von Constant Folding.

So führen Sie es aus

JMH ist eine separate Abhängigkeit (org.openjdk.jmh) und wird normalerweise über einen Annotationsprozessor sowie einen Maven-/Gradle-Build gestartet, der eine ausführbare JAR erzeugt. Sie führen Benchmarks nicht wie gewöhnlichen Code aus einer einfachen main-Methode heraus aus.

Statistik ist wichtig

JMH meldet nicht nur einen Durchschnitt, sondern auch das Fehler- bzw. Konfidenzintervall über mehrere Iterationen und Forks hinweg. Ein Ergebnis von 42.0 +/- 1.3 ns/op zeigt sowohl den zentralen Wert als auch seine Streuung — beides ist entscheidend, um einer Messung vertrauen zu können.

Wann Sie JMH einsetzen sollten

Verwenden Sie JMH, wenn Sie zwei Implementierungen eines häufig ausgeführten Pfads vergleichen, eine Optimierung überprüfen oder Operationen im Nanosekunden- bis Mikrosekundenbereich messen möchten. Für grobkörnige Vorgänge im Sekundenbereich (E/A, Netzwerk) ist eine Zeitmessung mit der Wanduhr normalerweise ausreichend.

Kurzer Test

Testen Sie Ihr Verständnis dafür, warum JMH benötigt wird.

Zusammenfassung

Sie haben gelernt, warum Microbenchmarking ein Harness benötigt:

  • Die JVM führt ein Warmup durch: Interpretierter Code wird erst nach vielen Aufrufen kompiliert.
  • Dead-Code-Eliminierung und Constant Folding können Ihre Arbeit entfernen oder vorab berechnen.
  • Schleifenoptimierungen und On-Stack-Replacement verfälschen handgeschriebene Schleifen.
  • JMH fügt Warmup-, Messiterationen, Forks, Blackhole und statistische Auswertungen hinzu.
  • Setzen Sie JMH ein, wenn Sie häufig ausgeführte Pfade im Nanosekundenbereich messen.

Häufig gestellte Fragen

Ist die Lektion „Warum JMH“ kostenlos?

Ja — der vollständige Text von „Warum JMH“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Warum JMH“?

Naive Fehler bei Benchmarks vermeiden Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Java Academy zu starten?

Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Warum JMH“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?

Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Warum JMH
  2. Einen Benchmark schreiben
  3. Aufwärmen und Iterationen
  4. Eliminierung toten Codes vermeiden
← Zurück zu Java Academy