0Pricing
Java Academy · Урок

Зачем нужен JMH

Избегайте наивных ошибок при измерениях

«Зачем нужен JMH» — бесплатный урок Java Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Зачем нужен JMH

Каркас микротестирования Java (JMH) — стандартный инструмент для измерения производительности небольших фрагментов кода Java. Самописные циклы измерения времени почти всегда дают неверные значения, поскольку JVM — это сложная оптимизирующая среда выполнения.

JMH создан для устранения этих проблем.

Наивный микротест

Обычно первая попытка заключается в том, чтобы обернуть цикл в System.nanoTime(). Это выглядит разумно, но для микротестов такой подход содержит серьёзные недостатки.

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);
    }
}

Проблема 1: прогрев JIT

JVM запускается в интерпретируемом режиме и компилирует горячие методы в машинный код только после тысяч вызовов. Наивный микротест измеряет медленную интерпретируемую фазу вместе с быстрой скомпилированной фазой, поэтому средние значения теряют смысл.

JMH решает эту проблему с помощью отдельной фазы прогрева, результаты которой отбрасываются.

Проблема 2: устранение мёртвого кода

Если вычисленный результат нигде не используется, JIT может полностью удалить вычисление. Тогда Ваш микротест измеряет пустой цикл.

JMH предоставляет использование возвращаемых значений и Blackhole, чтобы предотвратить это.

Проблема 3: свёртка констант

Если входные данные являются константами времени компиляции, JIT вычисляет ответ один раз и повторно использует его. В приведённом ниже примере компилятор может заменить весь цикл одной константой.

JMH использует объекты @State, чтобы входные данные оставались непрозрачными для оптимизатора.

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);
    }
}

Проблема 4: оптимизация циклов

JIT разворачивает циклы, выносит неизменяемый код и векторизует операции. Самописный цикл измеряет эти оптимизации, а не ту операцию, которую Вы хотели проверить.

JMH заменяет Ваш цикл тщательно контролируемым количеством итераций, которым управляет самостоятельно.

Проблема 5: замена на стеке

Долго выполняющийся цикл в main может быть скомпилирован во время выполнения (с помощью замены на стеке), что даёт характеристики производительности, отличающиеся от характеристик обычного скомпилированного метода. Это непредсказуемо искажает результаты.

Что предоставляет JMH

  • Отдельные итерации прогрева, результаты которых отбрасываются.
  • Несколько итераций измерения со статистикой.
  • Запуск в новых JVM, чтобы избежать загрязнения профилей.
  • Поглотитель и использование результатов для защиты от устранения мёртвого кода.
  • Объекты @State для предотвращения свёртки констант.

Как это запускать

JMH является отдельной зависимостью (org.openjdk.jmh) и обычно запускается с помощью обработчика аннотаций и сборки Maven/Gradle, создающей исполняемый JAR. Микротесты не запускают из обычного main, как обычный код.

Статистика важна

JMH сообщает не только среднее значение, но и погрешность / доверительный интервал по всем итерациям и отдельным запускам. Результат 42.0 +/- 1.3 ns/op показывает и центральное значение, и степень его изменчивости — это необходимо для доверия к измерению.

Когда использовать JMH

Используйте JMH при сравнении двух реализаций горячего участка кода, проверке оптимизации или измерении операций длительностью от наносекунд до микросекунд. Для продолжительных операций, занимающих секунды (ввод-вывод, сеть), обычно достаточно измерения реального времени.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете, зачем нужен JMH.

Итоги

Вы узнали, зачем микротестированию нужен специальный каркас:

  • JVM прогревается: интерпретируемый код становится скомпилированным только после множества вызовов.
  • Устранение мёртвого кода и свёртка констант могут удалить или заранее вычислить Вашу работу.
  • Оптимизации циклов и замена на стеке искажают самописные циклы.
  • JMH добавляет прогрев, итерации измерения, запуск в отдельных JVM, поглотитель и статистику.
  • Используйте его при измерении горячих участков кода, выполняющихся за наносекунды.

Часто задаваемые вопросы

Урок «Зачем нужен JMH» бесплатный?

Да — полный текст урока «Зачем нужен JMH» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Зачем нужен JMH»?

Избегайте наивных ошибок при измерениях Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.

Сколько времени занимает урок «Зачем нужен JMH»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужен JMH
  2. Написание измерения производительности
  3. Прогрев и итерации
  4. Предотвращение удаления неиспользуемого кода
← Назад к Java Academy