2015-01-24 7 views
7

Так я этот метод, написанный на Java:Где находится скомпилированный код JIT?

public void myMethod(int y){ 
    int x = 5 + y; 
    doSomething(x); 
} 

И предположим, мое приложение называет это много раз ..

При запуске скомпилированного кода для этого метода на Java Virtual Machine, JVM будет сначала интерпретируйте метод. Затем через некоторое время он решит скомпилировать его на машинный язык, если я правильно пойму.

На данный момент,

Будет ли перезаписана машинный код в памяти? Если он будет перезаписан, как будет решаться проблема разности размеров? Если он записан в другое место в памяти, будет ли освобожден байт-код загружен в память или нет? А также, если оба байта и jit скомпилированный код находятся в памяти, когда приложение снова обращается к этому методу, как JVM решает выполнить скомпилированный код jit вместо байтового кода?

+0

У меня возникла мысль, что это будет зависеть от того, работаете ли вы на машине под Windows или, скажем, на микроконтроллере с RAM-голоданием. Другими словами, зависит от платформы, нет? – Ghostkeeper

+2

Ответ 1: Почему вас это волнует? Ответ 2: JVM хранит код JITCed для каждого метода в C heap, связанный с помощью таблиц во внутреннем представлении объекта класса. Код удаляется только при завершении JVM или в редком случае, когда класс «разгружен». Все это управляется подходящей магией. –

+1

«C heap» на самом деле является неправильным здесь - если это относится к памяти, полученной с помощью вызовов в malloc (которые могут быть или не выровнены по страницам), соответствующие страницы должны быть отмечены как исполняемые. Скорее всего, JIT выделяет память для сгенерированного кода с помощью mmap, VirtualAlloc и тому подобного. –

ответ

12

HotSpot JVM имеет структуру Method в Metaspace (или PermGen в более ранних версиях). Он содержит метод bytecode, который никогда не перезаписывается и a pointer to compiled code, изначально NULL, пока не будет скомпилирован метод.

метод может иметь несколько точек входа:

  • _i2i_entry - указатель на интерпретатор байт-кода.
  • _code->entry_point() - точка входа в JIT-скомпилированный код. Скомпилированные методы располагаются в CodeCache - специальной области собственной памяти для динамически генерируемого кода виртуальной машины.
  • i2c и c2i адаптеры для вызова скомпилированного кода из интерпретатора и наоборот. Эти адаптеры необходимы, так как интерпретируемые методы и скомпилированные методы имеют различное соглашение о вызовах (способ, как передаются аргументы, как кадры построены и т.д.)

Скомпилированного метод может иметь необычные ловушки, которые попадают обратно в интерпретатор некоторые редкие случаи. Кроме того, метод Java может динамически перекомпилироваться несколько раз, поэтому JVM не может выбрасывать исходный байт-код. В любом случае нет смысла его освобождать, потому что байт-код обычно намного меньше, чем скомпилированный код.

5

Нет, это не перезаписывается, потому что в обоих представлениях, как правило, нет практического преимущества в одном месте. Байт-код JVM - это всего лишь часть данных. JIT-излучаемый код представляет собой поток собственных инструкций CPU (в некоторых архитектурах требуется, чтобы это явно было отмечено как исполняемый файл).

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

+1

Также: на многих современных платформах вы должны явно запрашивать * исполняемую * память из подсистемы виртуальной памяти. Нет никакой веской причины для того, чтобы байт-код был назначен на исполняемую страницу. –

2

Насколько я знаю, The Java® Virtual Machine Specification не указывает ни одно из них.
Единственная ссылка на JIT я могу найти в Chapter 3:

[...] Одним из примеров такого переводчика является точно в срок (JIT) генератор кода, который генерирует инструкции конкретной платформы только после загрузки кода виртуальной машины Java. В этой главе не рассматриваются проблемы, связанные с генерированием кода, а только те, которые связаны с компиляцией исходного кода, написанного на языке программирования Java, инструкциям Java Virtual Machine.

По моему мнению, это может быть сделано по-разному различными вариантами.

Однако мне кажется маловероятным, что память, содержащая байт-код java, перезаписывается встроенными инструкциями ЦПУ, поскольку инструкции CPU являются технически исполняемыми, а байт-код - это просто данные, поскольку их нужно интерпретировать. Однако это было бы невозможно, просто очень странно.

Смежные вопросы