Статьи

Компиляция Java Just-In-Time: больше, чем просто модное слово

Недавняя проблема с производительностью Java заставила меня вернуться и по-настоящему оценить компилятор Java VM Just-In-Time (JIT). Большинство Java-разработчиков и специалистов по поддержке слышали об этой оптимизации производительности времени выполнения JVM, но сколько из них действительно понимают и ценят ее преимущества? java_vm_JIT_buzzword

Эта статья поделится с вами упражнением в устранении неполадок, в котором я участвовал после добавления нового виртуального сервера (проект по повышению емкости и горизонтальному масштабированию).

Для более глубокого освещения JIT я рекомендую следующие статьи:

Обзор компиляции JIT

Компиляция JIT — это процесс, который улучшает производительность ваших Java-приложений во время выполнения.

Диаграмма ниже иллюстрирует различные уровни JVM и взаимодействие. Он описывает следующий процесс высокого уровня:

  1. Исходные файлы Java компилируются компилятором Java в независимый от платформы байт-код или файлы классов Java.
  2. После запуска Java-приложения JVM загружает скомпилированные классы во время выполнения и выполняет правильную семантику вычислений через интерпретатор Java.
  3. Когда JIT включен, JVM анализирует вызовы методов приложения Java и компилирует байт-код (после достижения некоторых внутренних порогов) в собственный, более эффективный, машинный код. Процесс JIT обычно отдается приоритет наиболее загруженным вызовам методов.
  4. Когда такой вызов метода компилируется в машинный код, JVM выполняет его напрямую, а не «интерпретирует» его.
  5. Вышеуказанный процесс приводит к улучшению производительности во время выполнения.

JVM_JIT_interraction

Тематическое исследование

Теперь вот история проекта, о котором я говорил ранее. Основная цель заключалась в добавлении нового виртуального сервера IBM P7 AIX (LPAR) в производственную среду для повышения пропускной способности платформы. Найдите ниже спецификации самой платформы:

  • Сервер Java EE : IBM WAS 6.1.0.37 и IBM WCC 7.0.1
  • ОС : AIX 6.1
  • JDK : IBM J2RE 1.5.0 (SR12 FP3 + IZ94331) @ 64-разрядная версия
  • СУБД : Oracle 10g
  • Тип платформы : Средний уровень и пакетная обработка

Для достижения существующих уровней производительности приложений были приобретены точно такие же технические характеристики оборудования. Версия ОС AIX и другое программное обеспечение IBM также были установлены с использованием той же версии, что и в существующей версии.

Следующие элементы (контрольный список) были проверены, чтобы гарантировать одинаковый уровень производительности приложения:

  • Аппаратные характеристики (# ядра процессора, физическая память, SAN…).
  • Версия ОС и уровень исправления; включая параметры ядра AIX.
  • Версия IBM WAS и IBM WCC, уровень исправления; в том числе параметры настройки.
  • Версия IBM JRE, уровень исправления и параметры настройки (параметры запуска, размер кучи Java …).
  • Сетевое подключение и производительность также были оценены должным образом.

После завершения сборки нового производственного сервера было проведено функциональное тестирование, которое также подтвердило правильное поведение сетевых и пакетных приложений.

Тем не менее, основная проблема с производительностью была обнаружена в самый первый день его производства. Ниже вы найдете сводную матрицу наблюдаемых проблем с производительностью.

Производственный сервер
Операция истекла время
Объем обработано (# заказов)
ЦПУ %
(средний)
Middleware health
Существующий сервер 10 часов 250 000 (базовый уровень) 20% здоровый
* Новый * сервер 10 часов 50 000 -500% 80% + 400% Высокая загрузка потока

Как видно из вышеприведенного представления, результаты производительности были довольно катастрофическими в первый рабочий день. Новый производственный сервер обработал не только намного меньше заказов, но использование физических ресурсов, таких как CPU%, было намного выше по сравнению с существующими производственными серверами.

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

Устранение неисправностей: поиск виновника…

Группа по устранению неисправностей была разделена на 2, чтобы сосредоточиться на следующих пунктах:

  • Определите источник CPU% из контейнера IBM WAS и сравните занимаемую площадь ЦП с существующим рабочим сервером.
  • Выполните дополнительные сравнения данных и файлов между существующим и новым рабочим сервером.

Чтобы понять источник CPU%, мы выполнили анализ AIX CPU на поток из IBM JVM, работающей под управлением IBM WAS и IBM WCC. Как вы можете видеть на скриншоте ниже, многие темы были найдены с использованием 5-20% каждый. Тот же анализ, выполненный на существующем производственном сервере, выявил меньшее количество потоков с загрузкой ЦП всегда около 5%.

JIT_CPU_per_Thread_analysis

Вывод:

Бизнес-процесс того же типа использует в 3-4 раза больше ЦП по сравнению с существующим производственным сервером.

Чтобы понять тип выполняемой обработки, дампы потока JVM были захвачены в то же самое время ЦПУ на данные Потока. Теперь первое, что мы поняли после просмотра дампа потоков JVM (ядро Java), это то, что JIT действительно был отключен! Проблема также была подтверждена запуском команды java –version из запущенных процессов JVM.

IBM_JVM_Javacore_JIT_disabled

Этот вывод был довольно серьезным, особенно учитывая, что JIT был включен на существующих производственных серверах. Примерно в то же время другая команда, отвечающая за сравнение серверов, наконец-то нашла различия между переменными среды пользователя AIX, использованного для запуска приложения. Такое сравнение было пропущено из более раннего анализа пробелов. Они обнаружили, что новый рабочий сервер AIX имеет следующую дополнительную запись:

1
JAVA_COMPILER=NONE

Согласно документации IBM , добавление такой переменной среды является одним из способов отключения JIT.

Комплексный анализ первопричин, простое решение

Чтобы понять влияние отключения JIT на нашу среду, вы должны понять его последствия. Отключение JIT означает, что вся JVM теперь работает в режиме интерпретации . Для нашего приложения работа в режиме полной интерпретации не только значительно снижает пропускную способность приложения, но также увеличивает точку нагрузки на использование ЦП сервера, поскольку каждый запрос / поток занимает в 3-4 раза больше ЦП, чем запрос, выполняемый с JIT (помните, когда JIT включен, JVM будет выполнять много вызовов непосредственно к машинному / собственному коду).

Как и ожидалось, удаление этой переменной среды вместе с перезапуском затронутых процессов JVM решило проблему и восстановило уровень производительности.

Оценка преимуществ JIT для вашего приложения

Я надеюсь, что вы оценили этот пример и краткий обзор процесса компиляции JVM JIT. Чтобы понять влияние неиспользования JIT для вашего Java-приложения, я рекомендую вам выполнить следующий эксперимент:

  • Создайте нагрузку на ваше приложение с включенным JIT и соберите некоторые базовые данные, такие как% CPU, время отклика, # запросов и т. Д.
  • Отключить JIT.
  • Повторите то же тестирование и сравните результаты.