90

JVM で JIT によって生成されたネイティブ コードを確認する方法はありますか?

4

7 に答える 7

81

一般的な使用法

他の回答で説明されているように、次の JVM オプションで実行できます。

-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly

特定の方法でフィルタリングする

次の構文を使用して、特定のメソッドでフィルター処理することもできます。

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

ノート:

  • OS などによっては、2 番目の引数を引用符で囲む必要がある場合があります。
  • メソッドがインライン化されると、いくつかの最適化を見逃す可能性があります

方法: Windows に必要なライブラリをインストールする

Windows を実行している場合、このページには、ビルドとインストールの方法hsdis-amd64.dllと、hsdis-i386.dllそれを機能させるために必要な手順が記載されています。そのページ*の内容を参照用に以下にコピーして拡張します。


ビルド済みバイナリの入手先

fcmlプロジェクトから Windows 用のビルド済みバイナリをダウンロードできます。

Windowshsdis-amd64.dllでのビルド方法hsdis-i386.dll

このバージョンのガイドは、64 ビットの Cygwin を使用して hsdis-amd64.dll を生成する Windows 8.1 64 ビットで作成されました。

  1. Cygwin をインストールしますSelect Packages画面で、次のパッケージを追加します (カテゴリを展開し、各パッケージ名の横にあるラベルDevelを 1 回クリックします)。Skip

    • make
    • mingw64-x86_64-gcc-core( にのみ必要hsdis-amd64.dll)
    • mingw64-i686-gcc-core( にのみ必要hsdis-i386.dll)
    • diffutils(Utilsカテゴリ内)
  2. Cygwin ターミナルを実行します。これは、インストーラーによって作成されたデスクトップまたはスタート メニュー アイコンを使用して行うことができ、Cygwin ホーム ディレクトリ (C:\cygwin\home\<username>\またはC:\cygwin64\home\<username>\デフォルト) が作成されます。

  3. 最新の GNU binutils ソース パッケージをダウンロードし、その内容を Cygwin ホーム ディレクトリに抽出します。執筆時点での最新パッケージはbinutils-2.25.tar.bz2. これにより、binutils-2.25Cygwin ホーム ディレクトリに (または最新バージョンが何であれ) という名前のディレクトリが作成されます。
  4. JDK 8 Updates リポジトリに移動し、インストールされている JRE バージョンに対応するタグを選択し、bz2 をクリックして、OpenJDK ソースをダウンロードします。hsdis ディレクトリ (にありsrc\share\toolsます) を Cygwin ホーム ディレクトリに抽出します。
  5. Cygwin ターミナルで、 と入力しcd ~/hsdisます。
  6. をビルドする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 バージョンに置き換えます。OS=LinuxCygwin は Linux に似た環境ですが、hsdis makefile はそれを認識できないため、これが必要です。

  7. ビルドはメッセージ./chew: No such file or directorygcc: command not found. <Cygwin home directory>\hsdis\build\Linux-amd64\bfd\MakefileWordpad や Notepad++ などのテキスト エディターで編集してSUBDIRS = doc po(binutils 2.25 を使用している場合は 342 行目) をSUBDIRS = po. 前のコマンドを再実行します。

hsdis\build\Linux-amd64DLL は、JRE またはディレクトリから、またはhsdis\build\Linux-i586JREbin\serverまたはディレクトリにコピーすることでインストールできますbin\client。を検索すると、システム上のそのようなディレクトリをすべて見つけることができますjava.dll

おまけのヒント: AT&T よりも Intel ASM 構文を好む場合は、-XX:PrintAssemblyOptions=intel使用する他の PrintAssembly オプションと一緒に指定してください。

※ページライセンスはクリエイティブコモンズ

于 2013-02-28T22:31:54.297 に答える
46

Sun Hotspot JVM (つまり、 Oracle によってjava.comで提供されているもの) を使用していると仮定すると、フラグを追加できます。

-XX:+PrintOptoAssembly

コードを実行するとき。これにより、JIT コンパイラによって生成された最適化されたコードが出力され、残りは除外されます。

最適化されていない部分を含むバイトコード全体を見たい場合は、

-XX:CompileThreshold=#

コードを実行しているとき。

このコマンドと JIT の一般的な機能の詳細については、こちらを参照してください。

于 2009-10-01T13:20:49.630 に答える
29

使用するには hsdis プラグインが必要ですPrintAssembly。便利な選択肢は、FCML ライブラリに基づく hsdis プラグインです。

UNIX ライクなシステム用にコンパイルでき、Windows では、Sourceforge の FCMLダウンロードセクションで入手できるビルド済みのライブラリを使用できます。

Windows にインストールするには:

  • dll を解凍します (hsdis-1.1.2-win32-i386.zip および hsdis-1.1.2-win32-amd64.zip にあります)。
  • dll が存在する場所にコピーします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

Linux にインストールするには:

  • ソースコードをダウンロードして解凍する
  • 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
  • 私のシステムでは、JDKが/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

追加の構成パラメーター:

codeニーモニックの前にマシンコードを表示します。
intel Intel 構文を使用します。
Gas AT&T アセンブラー構文 (GNU アセンブラー互換) を使用します。
dec IMM と変位を 10 進値で出力します。
mpad=XX命令のニーモニック部分のパディング。
cpad=XXマシンコードのパディング。
segデフォルトのセグメント レジスタを表示します。
zeros HEX リテラルの場合、先行ゼロを表示します。

Windows の場合は Intel 構文がデフォルトであり、GNU/Linux の場合は AT&T がデフォルトです。

詳細については、FCML ライブラリ リファレンス マニュアルを参照してください。

于 2014-07-02T06:28:30.523 に答える
8
于 2010-11-10T22:48:43.790 に答える
5

Windowsマシンで実行している場合、WinDbgが役立つと思います。私はちょうど1つの瓶を走らせました。

  • 次に、 Windbgを介して Java プロセスにアタッチしました
  • ~コマンドで調べたスレッド。11 個のスレッドがあり、0 個のスレッドがメインのワーカー スレッドでした
  • 0 スレッドに切り替え - ~0 秒
  • 管理されていないコールスタックを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 サブ esp,280h
    00402f71 53 プッシュ ebx
    00402f72 56 プッシュ esi
    00402f73 57 プッシュ edi
    ...など

追加情報については、プロセス エクスプローラーと WinDbg を使用してメモリ ダンプから JIT 処理されたコードをトレース バックする方法の例を次に示します。

于 2009-10-01T13:14:40.210 に答える
4

マシン コードと一部のパフォーマンス データを表示するもう 1 つの方法は、AMD の CodeAnalyst または OProfile を使用することです。これには、実行中の Java コードをマシン コードとして視覚化する Java プラグインが含まれています。

于 2010-11-10T22:23:22.637 に答える