Есть ли способ узнать из JVM, был ли конкретный метод скомпилирован JIT?

При написании микробенчмарков можно наблюдать большую разницу во времени выполнения в зависимости от того, скомпилирован метод или нет. Есть ли способ узнать из программы, был ли скомпилирован конкретный метод? В качестве альтернативы, есть ли способ запросить его или узнать, как его адекватно разогреть без какой-либо дополнительной информации, например, о. флаги переданы JVM? Очевидно, что это не обязательно будет идеально (например, может присутствовать какое-то условие, которое заставляет JVM возвращаться к интерпретируемому коду), но это, безусловно, будет улучшением.


person Rex Kerr    schedule 17.11.2012    source источник
comment
Вы можете эмпирически измерить время выполнения метода и проверить распределение результатов. Обычно у вас будет прыжок, когда он будет скомпилирован. На SO был вопрос об этой методологии, но я не могу найти его прямо сейчас. Очевидно, это несколько навязчиво.   -  person assylias    schedule 18.11.2012
comment
Я почти уверен, что нет, определенно нет.   -  person Louis Wasserman    schedule 18.11.2012
comment
@assylias - это работает, только если вы уверены, что метод еще не скомпилирован. В противном случае прыжка не найти. Кроме того, надежные алгоритмы обнаружения изменений очень сложно кодировать.   -  person Rex Kerr    schedule 18.11.2012


Ответы (2)


Для Sun/Oracle JVM вы можете использовать настройку -XX:CompileThreshold=1000.

Это, как указано в официальной документации, определяет :

Количество вызовов/ветвей метода перед компиляцией

Затем просто используйте номер, чтобы «разогреть» JVM.

Вы также можете использовать -XX:-PrintCompilation вместе с -XX:CompileThreshold, чтобы получать уведомления (в консоли) при компиляции метода.

person npe    schedule 17.11.2012
comment
Что такое ветка с точки зрения JVM? - person Rex Kerr; 18.11.2012
comment
@RexKerr - JVM пытается оценить, сколько времени тратится на метод (и, следовательно, сколько преимуществ будет от его компиляции), в основном путем подсчета записей и обратных ветвей (что указывает на циклы). Но могут быть и другие факторы, которые включены. - person Hot Licks; 18.11.2012
comment
Ну, это похоже на лучший доступный ответ, хотя он может быть неудовлетворительным. Спасибо! - person Rex Kerr; 06.12.2012

Я почти уверен, что вы можете включить ведение журнала, которое покажет, когда методы JITCed. Но я не знаю, как изнутри Java это сказать.

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

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

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

Добавлено: Одна вещь, о которой следует помнить при сравнительном анализе "фрагментов" кода, заключается в том, что самый внешний метод, выполняющий весь цикл, часто не поддерживает JITC (в зависимости от того, как реализован JITC) из-за к тому факту, что он никогда не возвращается и, следовательно, версия JITCed никогда не может быть вызвана. Таким образом, всегда следует помещать «мясо» кода, подлежащего тестированию, в отдельный метод, который вызывается повторно, а не помещать цикл и код, подлежащий тестированию, в один и тот же метод.

person Hot Licks    schedule 17.11.2012
comment
Я указал микробенчмарк. Большие приложения труднее определить. - person Rex Kerr; 18.11.2012
comment
Верно. Также следует помнить о сборке мусора, о том, имеет ли ваш тестовый пример ожидаемый уровень множественной отправки для реального кода, отбрасываются ли результаты и, таким образом, код может быть пропущен и т. д. и т. д. даже микротесты не так просто получить правильно ! - person Rex Kerr; 18.11.2012