Gibt es eine Möglichkeit, den von der JIT erzeugten nativen Code in einer JVM anzuzeigen?
Gibt es eine Möglichkeit, den von der JIT erzeugten nativen Code in einer JVM anzuzeigen?
Antworten:
Angenommen, Sie verwenden die Sun Hotspot-JVM (dh die von Oracle auf java.com bereitgestellte ), können Sie das Flag hinzufügen
-XX: + PrintOptoAssembly
wenn Sie Ihren Code ausführen. Dadurch wird der vom JIT-Compiler generierte optimierte Code ausgedruckt und der Rest weggelassen.
Wenn Sie den gesamten Bytecode einschließlich der nicht optimierten Teile anzeigen möchten, fügen Sie hinzu
-XX: CompileThreshold = #
wenn Sie Ihren Code ausführen.
Weitere Informationen zu diesem Befehl und der Funktionalität von JIT im Allgemeinen finden Sie hier .
Wie in anderen Antworten erläutert, können Sie mit den folgenden JVM-Optionen ausgeführt werden:
-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
Sie können auch nach einer bestimmten Methode mit der folgenden Syntax filtern:
-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
Anmerkungen:
Wenn Sie Windows ausführen, finden Sie auf dieser Seite Anweisungen zum Erstellen und Installieren hsdis-amd64.dll
sowie zu hsdis-i386.dll
den erforderlichen Funktionen. Wir kopieren unten und erweitern den Inhalt dieser Seite * als Referenz:
Wo Sie vorgefertigte Binärdateien erhalten
Sie können vorgefertigte Binärdateien für Windows aus dem fcml- Projekt herunterladen
Wie man hsdis-amd64.dll
und hsdis-i386.dll
unter Windows baut
Diese Version des Handbuchs wurde unter Windows 8.1 64-Bit mit 64-Bit-Cygwin erstellt und erzeugt hsdis-amd64.dll
Installieren Sie Cygwin . Fügen Sie auf dem Select Packages
Bildschirm die folgenden Pakete hinzu (indem Sie die Devel
Kategorie erweitern und dann einmal auf die Skip
Beschriftung neben jedem Paketnamen klicken ):
make
mingw64-x86_64-gcc-core
(nur benötigt für hsdis-amd64.dll
)mingw64-i686-gcc-core
(nur benötigt für hsdis-i386.dll
)diffutils
(in Utils
Kategorie)Führen Sie das Cygwin-Terminal aus. Dies kann über das vom Installationsprogramm erstellte Desktop- oder Startmenüsymbol erfolgen und erstellt Ihr Cygwin-Ausgangsverzeichnis ( C:\cygwin\home\<username>\
oder C:\cygwin64\home\<username>\
standardmäßig).
binutils-2.25.tar.bz2
. Dies sollte zu einem Verzeichnis mit dem Namen binutils-2.25
(oder der neuesten Version) in Ihrem Cygwin-Ausgangsverzeichnis führen.src\share\tools
) in Ihr Cygwin- Ausgangsverzeichnis .cd ~/hsdis
.Geben Sie zum Erstellen hsdis-amd64.dll
ein
make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
Geben Sie zum Erstellen hsdis-i386.dll
ein
make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
Ersetzen 2.25
Sie in beiden Fällen die heruntergeladene binutils-Version. OS=Linux
ist notwendig, da Cygwin zwar eine Linux-ähnliche Umgebung ist, das hsdis-Makefile es jedoch nicht als solches erkennt.
./chew: No such file or directory
und fehl gcc: command not found
. Bearbeiten Sie <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefile
in einem Texteditor wie Wordpad oder Notepad ++, um dies zu ändern SUBDIRS = doc po
(Zeile 342, wenn Sie binutils 2.25 verwenden) SUBDIRS = po
. Führen Sie den vorherigen Befehl erneut aus.Die DLL kann jetzt installiert werden, indem Sie sie von hsdis\build\Linux-amd64
oder hsdis\build\Linux-i586
in Ihre JREs bin\server
oder Ihr bin\client
Verzeichnis kopieren . Sie können alle diese Verzeichnisse auf Ihrem System finden, indem Sie nach suchen java.dll
.
Bonus-Tipp: Wenn Sie die Intel ASM-Syntax AT & T vorziehen, geben Sie diese zusammen -XX:PrintAssemblyOptions=intel
mit anderen von Ihnen verwendeten PrintAssembly-Optionen an.
* Seitenlizenz ist Creative Commons
/usr/lib/
Sie benötigen ein hsdis-Plugin, um es zu verwenden PrintAssembly
. Eine bequeme Wahl ist das auf der FCML-Bibliothek basierende hsdis-Plugin.
Es kann für UNIX-ähnliche Systeme kompiliert werden und unter Windows können Sie vorgefertigte Bibliotheken verwenden, die im FCML- Download- Bereich von Sourceforge verfügbar sind :
java.dll
(verwenden Sie die Windows-Suche). Auf meinem System habe ich es an zwei Stellen gefunden:
C:\Program Files\Java\jre1.8.0_45\bin\server
C:\Program Files\Java\jdk1.8.0_45\jre\bin\server
cd <source code dir>
./configure && make && sudo make install
cd example/hsdis && make && sudo make install
sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/lib/amd64/hsdis-amd64.so
sudo ln -s /usr/local/lib/libhsdis.so <JDK PATH>/jre/lib/amd64/hsdis-amd64.so
/usr/lib/jvm/java-8-oracle
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code
-jar fcml-test.jar
Zusätzliche Konfigurationsparameter:
Code Druckmaschinencode vor der Mnemonik.
Intel Verwenden Sie die Intel-Syntax.
gas Verwenden Sie die AT & T-Assembler-Syntax (GNU-Assembler-kompatibel).
dec Druckt IMM und Verschiebung als Dezimalwerte.
mpad = XX Auffüllen für den mnemonischen Teil der Anweisung.
cpad = XX Auffüllen des Maschinencodes.
seg Zeigt die Standardsegmentregister an.
Nullen HEX-Literalen werden führende Nullen angezeigt.
Die Intel-Syntax ist bei Windows eine Standardsyntax, während die AT & T-Syntax für GNU / Linux eine Standardsyntax ist.
Weitere Informationen finden Sie im FCML Library Reference Manual
apt-get install libhsdis0-fcml
( askubuntu.com/a/991166/489909 ). Dies selbst zu erstellen ist möglicherweise nicht erforderlich.
Für die HotSpot (war Sun) JVM auch in Produktmodi:
http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly
Einige Montage erforderlich: Es benötigt ein Plugin.
Ich glaube, WinDbg wäre hilfreich, wenn Sie es auf einem Windows-Computer ausführen. Ich habe gerade ein Glas laufen lassen.
Durch einen nicht verwalteten Callstack von kb geschaut gab es:
0008fba8 7c90e9c0 ntdll! KiFastSystemCallRet
0008fbac 7c8025cb ntdll! ZwWaitForSingleObject + 0xc
0008fc10 7c802532 kernel32! WaitForSingleObjectEx + 0xa8
0008fc24 00403a13 kernel32! WaitForSingleObject + 0x12
0008fc40 00402f68 java + 0x3a13
0008fee4 004087b8 java + 0x2f68
0008ffc0 7c816fd7 java + 0x87b8
0008fff0 00000000 kernel32! BaseProcessStart + 0x23
Hervorgehobene Zeilen führen direkt JIT-Code auf JVM aus.
Dann können wir nach der Methodenadresse suchen:
Java + 0x2f68 ist 00402f68
In WinDBG:
Klicken Sie auf Ansicht -> Demontage.
Klicken Sie auf Bearbeiten -> Gehe zu Adresse.
Setzen Sie 00402f68 dort
und bekam
00402f68 55 push ebp
00402f69 8bec mov ebp, esp
00402f6b 81ec80020000 sub esp, 280h
00402f71 53 push ebx
00402f72 56 push esi
00402f73 57 push edi
... und so weiter
Weitere Informationen finden Sie im Beispiel zum Zurückverfolgen von JIT-ed-Code aus Speicherabbildern mithilfe von Process Explorer und WinDbg.
Drucken Sie die Baugruppe Ihrer Hotspots mit den Perfasm-Profilern ( LinuxPerfAsmProfiler
oder WinPerfAsmProfiler
) von JMH . JMH benötigt die hsdis
Bibliothek, da sie darauf angewiesen ist PrintAssembly
.