Comment voir le code compilé JIT dans JVM?

Existe-t-il un moyen de voir le code natif produit par le JIT dans une JVM?

69
demandé sur assylias 2009-10-01 15:45:16

7 réponses

En supposant que vous utilisez la JVM Sun Hotspot (c'est-à-dire celle fournie sur java.com par Oracle), vous pouvez ajouter le drapeau

- XX: + PrintOptoAssembly

Lors de l'exécution de votre code. Cela imprimera le code optimisé généré par le compilateur JIT et laissera de côté le reste.

Si vous voulez voir le bytecode entier, y compris les parties non optimisées, ajoutez

- XX: CompileThreshold=#

Lorsque vous exécutez votre code.

Vous pouvez en savoir plus sur cette commande et la fonctionnalité de JIT en général ici .

39
répondu Falaina 2018-03-14 17:19:29

Générales d'utilisation de

Comme expliqué par d'autres réponses, vous pouvez exécuter avec les options JVM suivantes:

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

Filtrer sur une méthode spécifique

, Vous pouvez également filtrer sur une méthode spécifique avec la syntaxe suivante:

-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod

Notes:

  • vous devrez peut-être mettre le deuxième argument entre guillemets en fonction du système d'exploitation, etc.
  • si la méthode est InLine, vous pourriez manquer certaines optimisations

Comment: installer les bibliothèques requises sur Fenêtres

Si vous utilisez Windows, cette page contient des instructions sur la façon de construire et d'installer hsdis-amd64.dll et hsdis-i386.dll, qui sont nécessaires pour le faire fonctionner. Nous copions ci-dessous et étendons le contenu de cette page* pour référence:


Où trouver les binaires prédéfinis

Vous pouvez télécharger des binaires prédéfinis pour Windows à partir du fcml projet

Comment construire hsdis-amd64.dll et hsdis-i386.dll sur Windows

cette version du guide a été préparée sur Windows 8.1 64bit en utilisant Cygwin 64 bits et en produisant hsdis-amd64.dll

  1. Installer Cygwin. À l'écran Select Packages, ajoutez les paquets suivants (en développant la catégorie Devel, puis en cliquant une fois sur l'étiquette Skip à côté de chaque paquet nom):

    • make
    • mingw64-x86_64-gcc-core (seulement nécessaire pour hsdis-amd64.dll)
    • mingw64-i686-gcc-core (seulement nécessaire pour hsdis-i386.dll)
    • diffutils (dans la catégorie Utils)
  2. Exécutez le Terminal Cygwin. Cela peut être fait en utilisant L'icône du bureau ou du Menu Démarrer créée par le programme d'installation, et créera votre répertoire personnel Cygwin (C:\cygwin\home\<username>\ ou C:\cygwin64\home\<username>\ par défaut).

  3. Téléchargez le dernier paquet source GNU binutils et extrayez son contenu dans votre maison Cygwin répertoire. Au moment de la rédaction, le dernier paquet est binutils-2.25.tar.bz2. Cela devrait aboutir à un répertoire nommé binutils-2.25 (ou quelle que soit la dernière version) dans votre répertoire personnel Cygwin.
  4. Téléchargez la source OpenJDK en accédant au référentiel JDK 8 Updates , en sélectionnant la balise correspondant à votre version JRE installée et en cliquant sur bz2. Extrayez le répertoire hsdis (trouvé dans src\share\tools) dans votre répertoire personnel Cygwin.
  5. dans le Terminal Cygwin, entrez cd ~/hsdis.
  6. Pour construire hsdis-amd64.dll, entrez

    make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    Pour construire hsdis-i386.dll, entrez

    make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25

    Dans les deux cas, remplacez 2.25 par la version binutils que vous avez téléchargée. {[27] } est nécessaire car, bien que Cygwin soit un environnement de type Linux, le fichier makefile hsdis ne le reconnaît pas comme tel.

  7. la construction échouera avec les messages ./chew: No such file or directory et gcc: command not found. Modifier <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\Makefile dans un éditeur de texte comme Wordpad ou Notepad++ pour changer SUBDIRS = doc po (ligne 342, si en utilisant binutils 2.25) à SUBDIRS = po. Réexécutez la commande précédente.

La DLL peut maintenant être installée en la copiant depuis hsdis\build\Linux-amd64 ou hsdis\build\Linux-i586 vers le répertoire bin\server ou bin\client de votre JRE. Vous pouvez trouver tous ces répertoires sur votre système en recherchant java.dll.

Astuce Bonus: si vous préférez la syntaxe Intel ASM à AT & T, spécifiez -XX:PrintAssemblyOptions=intel à côté de toutes les autres options D'assemblage D'impression que vous utilisez.

*la licence de page est Creative Commons

64
répondu assylias 2015-11-05 23:16:19

Vous avez besoin d'un plugin hsdis pour utiliser PrintAssembly. Un choix pratique est le plugin hsdis basé sur la bibliothèque FCML.

Il peut être compilé pour les systèmes de type UNIX et sous Windows, vous pouvez utiliser des bibliothèques pré-construites disponibles dans la section FCML download sur Sourceforge:

Pour installer dans Windows:

  • extrayez la dll (elle peut être trouvée dans hsdis-1.1.2-win32-i386.zip et hsdis-1.1.2-win32-amd64.zip).
  • copiez la dll où existe java.dll (utilisez Windows rechercher). Sur mon système, je l'ai trouvé à deux endroits:
    • C:\Program Files\Java\jre1.8.0_45\bin\server
    • C:\Program Files\Java\jdk1.8.0_45\jre\bin\server

Pour installer sous Linux:

  • Téléchargez le code source, extrayez-le
  • 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
  • sur mon système, le JDK est dans /usr/lib/jvm/java-8-oracle

Comment l'exécuter:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly 
-XX:+LogCompilation -XX:PrintAssemblyOptions=intel,mpad=10,cpad=10,code 
-jar fcml-test.jar

Paramètres de configuration Supplémentaires:

code Imprimer le code machine avant de l' mnémonique.
intel utilise la syntaxe Intel.
gas utilise la syntaxe de l'assembleur AT&T (compatible GNU assembler).
dec affiche IMM et le déplacement en tant que valeurs décimales.
mpad = XX remplissage pour la partie mnémonique de l'instruction.
cpad = XX remplissage pour le code machine.
seg affiche les registres de segment par défaut.
les zéros montrent les zéros en tête dans le cas des littéraux hexadécimaux.

La syntaxe Intel est un un par défaut dans le cas de Windows, alors que L'AT & T est un par défaut pour GNU / Linux.

Pour plus de détails, voir le manuel de référence de la bibliothèque FCML

24
répondu swojtasiak 2017-03-26 19:41:50

Pour la JVM HotSpot (was Sun), même dans les modes produit:

Http://wikis.oracle.com/display/HotSpotInternals/PrintAssembly

Certains assembly requis: il a besoin d'un plugin.

8
répondu John Rose 2018-02-21 13:26:12

Je crois que WinDbg serait utile si vous l'exécutez sur une machine windows. Je viens d'utiliser un bocal.

  • Ensuite, je me suis attaché au processus java à travers Windbg
  • fils examinés par ~ commande; il y avait 11 threads, 0 thread était le thread de travail principal
  • commuté sur 0-thread - ~0s
  • Regardé à travers callstack non géré par kb Il y avait:

    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

Les lignes en surbrillance exécutent directement du code JIT-ed sur JVM.

  • Ensuite, nous pouvons chercher la méthode de l'adresse:
    java+0x2f68 est 00402f68

  • Sur WinDBG:
    Cliquez Sur Afficher --> Démontage.
    cliquez sur Modifier - > aller à Adresse.
    Mettez 00402f68 il
    et obtenu

    00402f68 55 push ebp
    00402f69 8bec MOV ebp, esp
    00402f6b 81ec80020000 sous esp, 280h
    00402f71 53 pousser ebx
    00402f72 56 pousser esi
    00402f73 57 push edi
    ... et ainsi sur

Pour plus d'informations, voici l'exemple comment retracer le code JIT-ed à partir de vidages de mémoire en utilisant process explorer et WinDbg.

5
répondu Andriy Tkach 2009-10-01 13:20:01

Une autre façon de voir le code machine et certaines données de performance est d'utiliser CodeAnalyst ou OProfile D'AMD, qui ont un plugin Java pour visualiser l'exécution de code Java en tant que code machine.

4
répondu Ian 2010-11-10 22:23:22

Imprimez l'assemblage de vos hotspots avec les profileurs perfasm de JMH (LinuxPerfAsmProfiler ou WinPerfAsmProfiler). JMH nécessite la bibliothèque hsdis car elle repose sur PrintAssembly.

0
répondu Aleksandr Dubinsky 2015-10-01 15:34:12