JVMのJITが生成するネイティブコードを確認する方法はありますか?
他の回答で説明されているように、次のJVMオプションで実行できます。
_-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
_
次の構文を使用して、特定のメソッドでフィルタリングすることもできます。
_-XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*MyClass.myMethod
_
ノート:
Windowsを実行している場合、 このページ には、動作させるために必要な_hsdis-AMD64.dll
_および_hsdis-i386.dll
_のビルドとインストールの方法が記載されています。以下をコピーして、参照用にそのページのコンテンツを拡張します。
ビルド済みのバイナリを入手する場所
Windows用のビルド済みバイナリを fcml プロジェクトからダウンロードできます
Windowsで_hsdis-AMD64.dll
_および_hsdis-i386.dll
_をビルドする方法
このバージョンのガイドは、64ビットCygwinを使用し、hsdis-AMD64.dllを生成するWindows 8.1 64ビットで作成されました
Cygwinのインストール 。 _Select Packages
_画面で、次のパッケージを追加します(Devel
カテゴリを展開し、各パッケージ名の横にあるSkip
ラベルを1回クリックします)。
make
mingw64-x86_64-gcc-core
_(_hsdis-AMD64.dll
_にのみ必要)mingw64-i686-gcc-core
_(_hsdis-i386.dll
_にのみ必要)diffutils
(Utils
カテゴリ内)Cygwinターミナルを実行します。これは、インストーラーによって作成されたデスクトップまたはスタートメニューアイコンを使用して行うことができ、Cygwinホームディレクトリ(デフォルトでは_C:\cygwin\home\<username>\
_または_C:\cygwin64\home\<username>\
_)が作成されます。
binutils-2.25.tar.bz2
_です。 Cygwinホームディレクトリに_binutils-2.25
_(または最新バージョンが何であれ)という名前のディレクトリが作成されます。src\share\tools
_にあります)をCygwinホームディレクトリに抽出します。cd ~/hsdis
_と入力します。_hsdis-AMD64.dll
_をビルドするには、次のように入力します。
make OS=Linux MINGW=x86_64-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
_hsdis-i386.dll
_をビルドするには、次のように入力します。
make OS=Linux MINGW=i686-w64-mingw32 'AR=$(MINGW)-ar' BINUTILS=~/binutils-2.25
どちらの場合も、_2.25
_をダウンロードしたbinutilsバージョンに置き換えます。 CygwinはLinuxのような環境ですが、hsdis makefileはそれを認識しないため、_OS=Linux
_が必要です。
./chew: No such file or directory
_および_gcc: command not found
_で失敗します。ワードパッドやメモ帳++などのテキストエディタで_<Cygwin home directory>\hsdis\build\Linux-AMD64\bfd\Makefile
_を編集して、_SUBDIRS = doc po
_(binutils 2.25を使用している場合は342行目)を_SUBDIRS = po
_に変更します。前のコマンドを再実行します。DLLは、これを_hsdis\build\Linux-AMD64
_または_hsdis\build\Linux-i586
_からJREの_bin\server
_または_bin\client
_ディレクトリにコピーすることでインストールできるようになりました。すべて見つかります_Java.dll
_を検索して、システム上のこのようなディレクトリを検索します。
おまけのヒント:AT&TよりもインテルASM構文を使用する場合は、使用する他のPrintAssemblyオプションとともに_-XX:PrintAssemblyOptions=intel
_を指定してください。
*ページのライセンスはクリエイティブ・コモンズです
PrintAssembly
を使用するには、hsdisプラグインが必要です。 FCMLライブラリに基づくhsdisプラグインが便利です。
UNIXライクなシステム用にコンパイルでき、WindowsではSourceforgeのFCML download セクションで利用可能なビルド済みライブラリを使用できます。
Java.dll
(Windows検索を使用)。私のシステムでは、次の2か所で見つかりました。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
追加の構成パラメーター:
コード ニーモニックの前にマシンコードを出力します。
インテル Intel構文を使用します。
ガス AT&Tアセンブラー構文を使用します(GNUアセンブラー互換)。
12月 IMMおよび変位を10進値として出力します。
mpad = XX 命令のニーモニック部分のパディング。
cpad = XX マシンコードのパディング。
ワンセグ デフォルトのセグメントレジスタを表示します。
ゼロ HEXリテラルの場合、先行ゼロを表示します。
Intelの構文はWindowsの場合のデフォルトの構文ですが、AT&Tの構文はGNU/Linuxのデフォルトです。
詳細については、 FCMLライブラリリファレンスマニュアルを参照してください
HotSpot(旧Sun)JVMの場合、製品モードでも:
http://wikis.Oracle.com/display/HotSpotInternals/PrintAssembly
いくつかのアセンブリが必要です:プラグインが必要です。
WinDbgは、Windowsマシンで実行している場合に役立つと思います。 1つのjarを実行しました。
kbによって無管理のコールスタックを調べたところ、
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
強調表示されている行は、JVMで直接実行されるJITされたコードです。
次に、メソッドのアドレスを探します。
Java + 0x2f68は00402f68
WinDBGの場合:
[表示]-> [逆アセンブリ]をクリックします。
[編集]-> [アドレスに移動]をクリックします。
そこに00402f68を置く
そして得た
00402f68 55プッシュebp
00402f69 8bec mov ebp、esp
00402f6b 81ec80020000 sub esp、280h
00402f71 53 Push ebx
00402f72 56 Push esi
00402f73 57 Push edi
...など
詳細については、ここに 例 プロセスエクスプローラーとWinDbgを使用してメモリダンプからJITされたコードをトレースバックする方法を示します。
マシンコードといくつかのパフォーマンスデータを確認する別の方法は、AMDのCodeAnalystまたはOProfileを使用することです。これらにはJavaプラグインがあり、Javaコードの実行をマシンコードとして視覚化します。
JMHのパフォーマンスプロファイラー(LinuxPerfAsmProfiler
またはWinPerfAsmProfiler
)を使用して、ホットスポットのアセンブリを印刷します。 JMHはhsdis
に依存しているため、PrintAssembly
ライブラリが必要です。