JVMが私のコードに適用した最適化を見つけるにはどうすればよいですか?
-
01-10-2019 - |
質問
JVM(特にHotspot VM)は、実行時に適用できる膨大な数の最適化があることで有名です。
特定のコードを見て、JVMが実際に行ったことを確認する方法はありますか?
解決
1つの問題は、「JVMが実際に行ったこと」が、JVMがコードを自由に再生成できるため、呼び出し間で変化することです。
例として、私は数日前にHotspotが何をしているのかを調査しました final
仮想方法と比較した方法。マイクロベンチマークから判断すると、私の結論は次のとおりです。
クライアントJVM:メソッドの場合 効果的に
final
(それを無効にするロードクラスはありません)、JVMは非仮想的な呼び出しを使用します。その後、このメソッドをオーバーライドするクラスをロードすると、JVMはJIT'edコードを変更して呼び出しを仮想にします。だからasを宣言しますfinal
重要な関連性はありません。サーバーJVM:こちら
final
関連性もないようです。起こっているように思われることは、JVMが使用しているクラスの非仮想呼び出しを生成することです 初めて, 、ロードされたクラスとは独立して。その後、別のクラスのオブジェクトから電話をかけた場合、JVMはこれに似たものですべての呼び出しにパッチを当てます(コールもプロファイルするので、速いパスとスローパスを変えることができないと思います。初めてです):
if (object instanceof ClassOfNonVirtualCall) { do non-virtual call to ClassOfNonVirtualCall.method } else { do virtual call to object.method }
生成されたコードを見ることに本当に興味がある場合は、OpenJDKのDebug JVMSで再生できます。
他のヒント
これは非常にJVM固有であり、あなたが見ている特定のJVMでいくつかの真剣な調査を行う必要があるでしょう。
ここで利用可能なHotspot VMオプションを見ることができます http://www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.html
以下は非常に優れたリソースです。
http://wikis.sun.com/display/hotspotinternals/home
特に興味深いのは、「ログコンピレーションツール」と「ログコンピレーションの概要」リンクです(登録したときに直接リンクを投稿できません)。
これが良いページです ホットスポットの最適化。いくつかの最適化は、コンパイラによって放出されるバイトコードを見ることで見ることができます。他の最適化は動的であり、実行時にのみ存在します。たとえば、Hotspotは実行できます オンスタックの交換 ランタイム中にスタックを直接変更します。