Wo befindet sich der kompilierte JIT-Code?

7

Also ich habe diese Methode, in Java geschrieben:

%Vor%

Und nehme an, dass meine Anwendung das oft aufruft.

Wenn der kompilierte Code für diese Methode auf der Java Virtual Machine ausgeführt wird, interpretiert JVM die Methode zuerst. Dann wird es nach einiger Zeit entscheiden, es zu kompilieren, wenn ich es richtig verstanden habe.

An diesem Punkt

Wird es durch den Maschinencode im Speicher überschrieben? Wenn es überschrieben wird, wie wird das Problem der Größenunterschiede gelöst? Wenn es an einen anderen Ort im Speicher geschrieben wird, wird der Bytecode in den Speicher geladen oder nicht freigegeben? Und wenn sowohl der Bytecode als auch der kompilierte jit-Code im Speicher ist, wie entscheidet sich die JVM dann, wenn die Anwendung diese Methode erneut antrifft, statt den Bytecode den jit-kompilierten Code auszuführen?

    
Koray Tugay 24.01.2015, 13:40
quelle

3 Antworten

12

HotSpot JVM hat eine Methode Struktur in Metaspace (oder PermGen in früheren Versionen). Es enthält Methode Bytecode, der nie überschrieben wird und ein Zeiger auf den kompilierten Code , anfänglich NULL, bis die Methode kompiliert wurde.

Eine Methode kann mehrere Einstiegspunkte haben:

  • _i2i_entry - ein Zeiger auf den Bytecode-Interpreter.
  • _code->entry_point() - ein Einstiegspunkt für den JIT-kompilierten Code. Kompilierte Methoden befinden sich in CodeCache - der speziellen Region des nativen Speichers für den dynamisch generierten VM-Code.
  • i2c und c2i Adapter, um den kompilierten Code vom Interpreter aufzurufen und umgekehrt. Diese Adapter werden benötigt, weil die interpretierten Methoden und die kompilierten Methoden unterschiedliche Aufrufkonventionen haben (die Art und Weise, wie Argumente übergeben werden, wie Frames konstruiert werden usw.)

Eine kompilierte Methode kann in seltenen Fällen ungewöhnliche Traps enthalten, die auf den Interpreter zurückfallen. Außerdem kann eine Java-Methode mehrmals dynamisch neu kompiliert werden, so dass JVM den ursprünglichen Bytecode nicht wegwerfen kann. Es hat keinen Sinn, es trotzdem zu befreien, weil der Bytecode normalerweise viel kleiner ist als der kompilierte Code.

    
apangin 24.01.2015, 15:07
quelle
5

Nein, es wird nicht überschrieben, weil es normalerweise keinen praktischen Nutzen gibt, wenn die zwei Darstellungen am gleichen Ort sind. Der JVM-Bytecode ist nur ein Stück Daten. Der JIT-emittierte Code ist ein Strom von nativen CPU-Anweisungen (in einigen Architekturen ist es erforderlich, dass dies explizit als ausführbar markiert wird).

Wenn eine neue Funktion für die Ausführung benötigt wird, liest der JIT-Compiler typischerweise den Bytecode dieser Funktion, weist Speicher irgendwo anders zu, schreibt den entsprechenden nativen Code in diesen Speicher und gibt dann einen Funktionszeiger an den Eintrag des neu erzeugten systemeigener Code.

    
quelle
2

Soweit ich weiß, Die Java® Virtual Machine-Spezifikation gibt nichts davon an.
Der einzige Hinweis auf JIT, den ich finden kann, ist in Kapitel 3 :

  

[...] Ein Beispiel für einen solchen Übersetzer ist ein Just-in-Time (JIT) -Codegenerator, der plattformspezifische Anweisungen erst generiert, nachdem Java Virtual Machine-Code geladen wurde. Dieses Kapitel befasst sich nicht mit Problemen im Zusammenhang mit der Codegenerierung, sondern nur mit denjenigen, die mit dem Kompilieren von Quellcode in der Java-Programmiersprache in Java Virtual Machine-Anweisungen verknüpft sind.

Nach meinem Verständnis kann dies durch verschiedene Implementierungen anders durchgeführt werden.

Mir erscheint es jedoch sehr unwahrscheinlich, dass der Speicher, der den Java-Bytecode enthält, mit nativen CPU-Anweisungen überschrieben wird, da CPU-Anweisungen technisch ausführbar sind und Bytecode nur Daten sind, wie sie interpretiert werden müssen. Es wäre jedoch nicht unmöglich, nur sehr seltsam.

    
Siguza 24.01.2015 13:51
quelle

Tags und Links