Подтвердить что ты не робот

Техника или утилита для минимизации времени "разминки" Java?

Я поддерживаю приложение обмена сообщениями Java, которое требует низкой задержки (< 300 микросекунд, обрабатывающих каждое сообщение). Тем не менее, наше профилирование показывает, что виртуальная машина Sun Java сначала запускается медленно и ускоряется после первых 5000 сообщений или около того. Первые 5000 сообщений имеют латентность 1-4 миллисекунды. После того, как первые 5000, последующие сообщения имеют задержку ~ 250 микросекунд, со случайными выбросами.

В целом понятно, что это типичное поведение для Java-приложения. Однако, с точки зрения бизнеса, неприемлемо сообщать клиенту, что им приходится ждать, пока JVM "разогревается", прежде чем увидит, какую производительность они требуют. Приложение должно быть "разогрето" перед обработкой первого сообщения клиента.

JVM - обновление Sun 1.6.0 4.

Идеи для преодоления этой проблемы:

  • Настройки JVM, такие как -XX: CompileThreshold =
  • Добавить компонент для "разминки" приложения при запуске, например, путем отправки "поддельных сообщений" через приложение.
  • Статически загружать приложение и классы JDK при запуске приложения, чтобы классы не загружались из JAR при обработке клиентских сообщений.
  • Некоторая утилита или агент Java, который выполняет одну или обе из этих двух идей, так что мне не нужно повторно изобретать колесо.

ПРИМЕЧАНИЕ. Очевидно, что для этого решения я рассматриваю все факторы, включая микросхему, тип диска и конфигурацию и настройки ОС. Однако для этого вопроса я хочу сосредоточиться на том, что можно сделать для оптимизации приложения Java и свести к минимуму "разогрев" времени.

4b9b3361

Ответ 1

"Разминка" на Java обычно имеет две вещи:

(1): Lazy class loading: Это может быть полезно, чтобы загрузить его.

Легкий способ сделать это - отправить фальшивое сообщение. Вы должны быть уверены, что поддельное сообщение вызовет весь доступ к классам. Для exmaple, если вы отправляете пустое сообщение, но ваш прогром проверяет, пустое ли сообщение и не позволяет делать определенные вещи, тогда это не сработает.

Другой способ сделать это - принудительно инициализировать класс, обратившись к этому классу при запуске программы.

(2): Оптимизация в реальном времени: во время выполнения Java VM оптимизирует часть кода. Это основная причина, по которой происходит время прогрева.

Чтобы облегчить это, вы можете отправить кучу поддельных (но выглядите реальных) сообщений, чтобы оптимизация могла завершиться до того, как пользователь ее использовал.

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

Надеюсь, что это поможет.

Ответ 2

Ваша проблема не в загрузке классов, а в компиляции "только во времени".

Попробуйте -XX:CompileThreshold=1

Это заставит Java скомпилировать все при первом запуске. Это несколько замедлит запуск вашего кода, но не код VM (поскольку он скомпилируется при установке Java). Существует ошибка, позволяющая Java скомпилировать пользовательские JAR аналогичным образом и сохранить результат для последующих исполнений, что значительно снизит эти накладные расходы, но в ближайшее время не будет необходимости исправлять эту ошибку.

Второй вариант - отправить 5 000 поддельных сообщений в приложение, чтобы "разогревать". Продайте это как "убедившись, что все настроено правильно".

[EDIT] Некоторая справочная информация в прекомпиляции классов: Обмен данными классов

Возможно, вы захотите попробовать IBM-версию Java, так как здесь вы можете добавить больше классов в общий пул: Обзор совместного использования данных класса

[EDIT2] Чтобы ответить на вопросы, поднятые kittylyst: Это правда, что это быстро заполнит ваш кеш кода методами, которые используются только один раз. И это может даже сделать все ваше приложение медленнее.

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

Основная проблема здесь в том, что код все еще компилируется "как раз вовремя". Пока вы не можете запускать каждый метод, который вам нужен хотя бы один раз, приложение будет "hickup" в течение нескольких миллисекунд каждый раз, когда он встречает что-то, что еще не было скомпилировано раньше.

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

Ответ 3

Просто запустите кучу сообщений no-op через систему, прежде чем она откроется для подлинного клиентского трафика. 10k сообщений - это обычный номер.

Для финансовых приложений (например, FIX) это часто делается путем отправки заказов (по цене, далекой от последней ночи, на всякий случай) до выхода на рынок. Все они будут отвергнуты, но это не имеет значения.

Если используемый протокол является доморощенным, то в следующий раз, когда вы обновите библиотеки для него, добавьте явную поддержку типов сообщений "WARMUP" или "TEST" или "SANITYCHECK".

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

Ответ 4

Используете ли вы клиент или сервер JVM? Попробуйте запустить свою программу с помощью:

java -server com.mycompany.MyProgram

При запуске Sun JVM в этом режиме JIT будет компилировать байт-код на собственный код раньше; из-за этого программе потребуется больше времени, но после этого она будет работать быстрее.

Ссылка: Часто задаваемые вопросы о виртуальной машине Java HotSpot

Цитата:

Какая разница между системами -client и -server?

Эти две системы представляют собой разные бинарные файлы. Это, по существу, два разных компилятора (JIT), взаимодействующие с одной и той же системой времени исполнения. Клиентская система оптимальна для приложений, которым требуется быстрое время запуска или небольшие отпечатки, серверная система оптимальна для приложений, где общая производительность является наиболее важной. В целом клиентская система лучше подходит для интерактивных приложений, таких как графические интерфейсы. Некоторые из других различий включают политику компиляции, значения по умолчанию для кучи и политику вложения.

Ответ 5

Если вы работаете в режиме сервера Hotspot на современном оборудовании (с 2 или более ядрами на процессор) и с последней версией JDK, то для ускорения разогрева можно использовать следующую опцию:

-server -XX:+TieredCompilation

Ответ 6

Старый поток, я знаю, но нашел это в Интернете:

Очень интересной является влияние опции-XX: CompileThreshold = 1500 на SUN HotSpot JVM. По умолчанию используется 10000 для VM сервера и 1500 для клиентской виртуальной машины. Однако установка его на 1500 для Server VM делает его быстрее, чем клиентская VM. Установка на 100 действительных значений снижает производительность. И использование опции-Xcomp (что означает, что весь код скомпилирован перед использованием) дает еще более низкую производительность, что удивительно.

Теперь вы знаете, что делать.