Как jProfiler обрабатывает JIT?

Я использую jProfiler экстенсивно, и это отличный инструмент, но мне интересно, как jProfiler обрабатывает эффекты компиляции JIT.

Могу ли я наблюдать, например, метод вложения? Если метод встроен, он вообще не будет отображаться в снимке или jProfiler все еще способен вычислить время его выполнения?

Аналогично, метод, который не имеет побочных эффектов и может быть полностью оптимизирован, также не будет показан в jProfiler. Правильно ли это?

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

Ответ 1

Я использую jProfiler экстенсивно, и это отличный инструмент, но мне интересно, как jProfiler обрабатывает эффекты компиляции JIT.

Компиляция "точно в срок" на самом деле является довольно старой технологией, которая заменила адаптивный оптимизатор HotSpot. JIT слепо компилирует каждый метод из байт-кода Java в собственный код и может (или не может) оптимизировать его.

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

Можно ли наблюдать, например, метод inline? Если метод встроен, он вообще не будет отображаться в снимке или jProfiler все еще способен вычислить время его выполнения?

JProfiler не сообщит, какие методы были встроены; однако он будет с радостью сообщать о своих вызовах, даже если компилятор разместил их встроенными в другой метод.

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

Аналогично, метод, который не имеет побочных эффектов и может быть полностью оптимизирован, также не будет показан в jProfiler. Правильно ли это?

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

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

Разница в выборке и инструментах объясняется в в этой статье.