Каковы различия в JIT между Java и .Net - PullRequest
14 голосов
/ 24 марта 2010

Я знаю, что Microsoft .NET использует CLR в качестве JIT-компилятора, в то время как в Java есть Hotspot. В чем различия между ними?

1 Ответ

23 голосов
/ 16 апреля 2010

Они очень разные звери. Как указывали люди, CLR компилируется в машинный код перед тем, как выполнить фрагмент MSIL. Это позволяет ему в дополнение к типичному устранению мертвого кода и выстраиванию рядовых оптимизаций использовать преимущества конкретной архитектуры ЦП целевой машины (хотя я не уверен, что это так). Это также влечет за собой успех для каждого класса (хотя компилятор довольно быстрый, и многие библиотеки платформ являются лишь тонким слоем над Win32 API).

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

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

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

Тем не менее, HotSpot - это только одна из виртуальных машин. JRockit, Azul, IBM J9 и сбрасываемый RVM - все имеют разные профили производительности.

...