JVM(特にHotSpot VM)は、実行時に適用できる最適化の数が非常に多いことで有名です。
特定のコードを調べて、JVMが実際にそれに対して何をしたかを確認する方法はありますか?
JVM(特にHotSpot VM)は、実行時に適用できる最適化の数が非常に多いことで有名です。
特定のコードを調べて、JVMが実際にそれに対して何をしたかを確認する方法はありますか?
問題の 1 つは、JVM が自由にコードを再生成できるため、呼び出しごとに「JVM が実際に行ったこと」が変化することです。
final
例として、数日前にホットスポットが仮想メソッドと比較してメソッドで何をするかを調査しました。マイクロベンチマークから判断すると、私の結論は次のとおりです。
クライアント JVM: メソッドが有効な final
場合(それをオーバーライドするロード済みクラスがない場合)、JVM は非仮想呼び出しを使用します。その後、このメソッドをオーバーライドするクラスをロードすると、JVM は JIT されたコードを変更して呼び出しを仮想化します。そのため、 as を宣言しfinal
ても重要な関連性はありません。
サーバー JVM: こちらfinal
も関連性がないようです。何が起こっているように見えるかというと、ロードされたクラスに関係なく、JVMが初めて使用しているクラスに対して非仮想呼び出しを生成することです。その後、別のクラスのオブジェクトから呼び出しを行うと、JVM はすべての呼び出しにこれと同様のパッチを適用します (呼び出しのプロファイリングも行うため、取得できなかった場合に高速パスと低速パスを変更できます)。それは初めてです):
if (ClassOfNonVirtualCall のオブジェクト インスタンス) { ClassOfNonVirtualCall.method への非仮想呼び出しを行う } そうしないと { object.method への仮想呼び出しを行う }
生成されたコードを見ることに本当に興味がある場合は、OpenJDK の DEBUG JVM で遊ぶことができます。
これは非常にJVM固有であり、見ている特定のJVMで深刻な調査を行う必要がある可能性があります。
利用可能なHotSpotVMオプションは、http: //www.oracle.com/technetwork/java/javase/tech/vmoptions-jsp-140102.htmlで確認できます。
以下は非常に優れたリソースです。
http://wikis.sun.com/display/HotSpotInternals/Home
特に興味深いのは、「LogCompilation ツール」と「LogCompilation の概要」のリンクです (登録したばかりなので、直接リンクを投稿できません)。
これは、 HotSpotの最適化に関する優れたページです。いくつかの最適化は、コンパイラーによって発行されたバイトコードを見るとわかります。その他の最適化は動的であり、実行時にのみ存在します。たとえば、HotSpotは、実行時にスタックを直接変更するスタック上の置換を実行できます。