Ответ 1
Для потомков это было довольно просто, как только я прочитал некоторый исходный код JVM hotspot.
В следующих флагах указывается точная строка исходного кода, которая приводит к деоптимизации и повторной смене функции:
-XX:+TraceDeoptimization -XX:+WizardMode -XX:+PrintNativeNMethods -XX:+PrintDependencies -XX:+DebugDeoptimization -XX:+LogEvents
Обычно это был оператор if.
void function (Object object){
if ( object == null ){
// do some uncommon cleanup or initialization
}
do_stuff();
}
Скажем, мой код разминки никогда не запускал оператор if.
Я предположил, что вся функция будет скомпилирована за один раз, однако, когда компилятор JIT C2 фактически решил создать собственный код для этой функции, он не будет генерировать код для оператора if, поскольку этот путь кода никогда не принимался.
Он генерирует только условную ветвь, которая генерирует обработчик ловушки и исключения в потоке компилятора C2. Я думаю, что это происходит из-за того, что кеш собственного кода был/довольно небольшим, и поэтому сценарий JVM не хотел заполнять его потенциально бесполезным кодом.
В любом случае, если утверждение всегда истинно (т.е. объект всегда имеет значение null), тогда функция немедленно и безоговорочно инициирует эту обработку исключений и будет повторно скомпилирована (что приведет к хищению заморозки/задержки в порядке пары мс).
Конечно, мой код разминки не будет вызывать каждую функцию точно так же, как и производство, и я бы рискнул предположить, что в любом сложном продукте это все равно невозможно и кошмар обслуживания в любом случае.
Это означает, что для эффективного разогрева приложения Java каждый отдельный if-оператор в коде должен быть вызван по развороту кода.
Итак, мы собираемся просто отказаться от идеи "разогревать" наш Java-код, потому что это не так просто, как полагают некоторые.
По следующим причинам мы собираемся перезаписать части приложения для поддержки работы в течение нескольких недель/месяцев за раз:
- Простое обслуживание (нам не нужно моделировать производство во время разминки и обновлять его).
- JIT не будет выполняться в соответствии с нашими пластическими симуляциями, но вместо этого будет работать с производством (т.е. использовать JIT для того, для чего он был разработан вместо того, чтобы бороться с ним).
Долгосрочный клиент, скорее всего, заплатит за переписывание на C/С++ или подобное, чтобы получить постоянную низкую задержку, но в течение другого дня.
EDIT: Позвольте мне добавить, что обновление до более новой версии JVM Hotspot или "настройка" вокруг параметров JVM точки доступа никогда не решит эту проблему. Они оба - дымы и зеркала. Дело в том, что JVM Hotspot никогда не был написан для предсказуемой малой задержки, и этот недостаток невозможно обойти из пользовательского пространства java.