JIT срабатывает ПОСЛЕ того, как определенный фрагмент кода был выполнен много раз.
HotSpot JVM попытается определить «горячие точки» в вашем коде. Горячие точки - это фрагменты вашего кода, которые выполняются много-много раз. Для этого JVM будет «подсчитывать» выполнение различных инструкций, и когда он определяет, что определенная часть выполняется часто, он запускает JIT. (это приблизительное значение, но это легко понять, если объяснить это так).
JIT (Just-In-Time) берет этот кусок кода и пытается сделать его быстрее.
Методы, используемые JIT для ускорения работы вашего кода, очень распространены, но чаще всего возникает путаница:
- Он попытается определить, использует ли этот фрагмент кода переменные, которые больше нигде не используются (бесполезные переменные), и удалить их.
- Если вы получаете и снимаете одну и ту же блокировку несколько раз (например, вызываете синхронизированные методы одного и того же объекта), он может получить блокировку один раз и выполнить все вызовы в одном синхронизированном блоке
- Если вы обращаетесь к членам объекта, которые не объявлены как volatile, он может решить оптимизировать его (поместить значения в регистры и т. П.), Создавая странные результаты в многопоточном коде.
- Это будут встроенные методы, чтобы избежать стоимости звонка.
- Будет преобразован байт-код в машинный код.
- Если цикл полностью бесполезен, его можно полностью удалить.
Итак, правильный ответ на ваш вопрос заключается в том, что пустой цикл после JITed не требует времени для выполнения ... скорее всего, его больше нет.
Опять же, есть много других оптимизаций, но по моему опыту, они являются одними из тех, которые создали большинство головных болей.
Более того, JIT улучшается в любой новой версии Java, и иногда он даже немного отличается в зависимости от платформы (поскольку в некоторой степени зависит от платформы). Оптимизации, выполняемые JIT, трудно понять, потому что вы обычно не можете найти их, используя javap и проверяя байт-код, даже если в последних версиях Java некоторые из этих оптимизаций были перемещены непосредственно в компилятор (например, начиная с Java 6, компилятор возможность обнаруживать и предупреждать о неиспользуемых локальных переменных и частных методах).
Если вы пишете какие-то циклы для проверки чего-либо, обычно рекомендуется иметь цикл внутри метода, вызывать метод несколько раз ПЕРЕД синхронизацией, чтобы дать ему раунд «ускорить», а затем выполнить синхронизированный цикл
Обычно это запускает JIT в простой программе, подобной вашей, даже если нет гарантии, что она действительно сработает (или что она вообще существует на определенной платформе).
Если вы хотите стать параноиком по поводу JIT или не JIT синхронизации (я это сделал): сделайте первый раунд, рассчитывая время каждого выполнения цикла, и дождитесь стабилизации времени (например, отличие от среднего менее 10% ), затем начните со своего «реального» времени.