web-dev-qa-db-ja.com

JVMに特定のメソッドをネイティブにコンパイルするように強制できますか?

アプリの起動時に頻繁に呼び出されるパフォーマンスクリティカルなメソッドがあります。最終的には、JITコンパイルされますが、インタプリタでかなりの時間が実行された後ではありません。

このメソッドを最初からコンパイルする必要があることをJVMに伝える方法はありますか(-XX:CompileThresholdなどで他の内部を調整することなく)?

31

私が知っている唯一の方法は-Xcompフラグですが、これを使用することは一般的にはお勧めできません。すべてのクラスとメソッドが最初に実行されたときに、それらのJITコンパイルを即座に強制します。欠点は、最初の起動時にパフォーマンスが低下することです(JITアクティビティの増加による)。このフラグのその他の主な制限は、JITが通常行うインクリメンタルプロファイリングベースの最適化を無効にしているように見えることです。標準の混合モードでは、JITコンパイラーは、収集されたプロファイリングと実行時情報に基づいて、コードの一部を継続的に最適化解除および再コンパイルできます(そして再コンパイルします)。これにより、省略されたが必要であることが判明した境界チェック、次善のインライン化などの誤った最適化を「修正」できます。-Xcompはプロファイリングベースの最適化を無効にし、プログラムによっては、全体としてわずかなパフォーマンスの大幅な低下を引き起こす可能性があります。または、起動時に実際の利益がないため、使用をお勧めしません。

-Xcomp(かなり残酷です)と-XX:CompileThreshold(JITがコンパイル/最適化する前に統計を収集するために解釈モードで実行される特定のメソッドの実行回数を制御します)の他に、-Xbatchもあります。これにより、JITコンパイルが「フォアグラウンド」に強制され、通常のようにバックグラウンドでコンパイルするのではなく、コンパイルされるまでメソッドの呼び出しが基本的にブロックされます。

使用しているJavaバージョンを指定していませんが、Java 7がオプションの場合、「階層型コンパイル」と呼ばれる新しいJITモデルが導入されます。 "(-XX:+TieredCompilationスイッチでアクティブ化されます。)階層型コンパイルが行うことは、メソッドの最初の使用時に最初の小さなコンパイルパスを許可し、収集されたプロファイリングデータに基づいて後で追加の大きなコンパイル/最適化を行うことです。あなたにとって興味深いはずです。

おそらくいくつかの追加の調整とパラメーター/構成が必要ですが、私はそれをさらにチェックすることに取り掛かっていません。

36
pap