3

重複の可能性:
JVMがJITコンパイル済みコードをキャッシュしないのはなぜですか?

JITコンパイルは、ホットスポットメカニズムを使用したネイティブコードへのコンパイルであり、OSやHardwardsなどへの最適化であるため非常に高速である可能性があることを理解しています。

私の質問は、なぜJavaはそのJIT準拠のコードをファイルのどこかに保存せず、将来の目的のために同じものを使用しないのですか?これにより、「初期ウォームアップ」時間も短縮できます。

ここで欠けているものを教えてください。

私の質問に追加するには:Javaが完全なコードをネイティブに準拠させ、それを常に(特定のJVM、OS、プラットフォームに対して)使用しないのはなぜですか?なぜJITなのか?

4

5 に答える 5

3

常にJVMを使用するという保証はありますが、常に同じJVMを使用するという保証はありません。ホットスポットに最適化されたコードは、ご使用のマシンでのみ有効です。

Javaでは、コードがJVMに対してローカルであるという保証はありません。アプレットは完璧な例であり、Webstartもこの点を示しています。一般的な「最適化を維持する」は、めったに実行されないコードでキャッシュを乱雑にするだけであり、最適化された拡張機能を維持する場所に問題を引き起こします。

また、ディスク上のキャッシュを保持する期間を知るのにかなりのパズルが作成されます。キャッシュがクラスファイルの正しい「リリース」用であることを確認するために、「クラス」ファイルを再コンパイルする必要はありませんか。オプションのシリアルバージョンuidを除いて、Javaには同じクラスファイル指定子の「このバージョン」はありません。

おそらく、クラスファイルを合計してコンパイル済みクラスのフィールドに配置することで回避策がありますが、キャッシュされたすべてのマシン固有のコードをスキャンし、テーブルを作成し、クラスローダー、および最適化されたコードでロードされたクラスのチェックサムをチェックします。

于 2012-07-25T15:02:37.417 に答える
2

私は自分でこの質問をしました。私が得た印象は、正しく理解するのが非常に難しく、古いコードを含むストアを避けることです。

この問題を回避する1つの方法は、-XX:+PrintCompilationこれらのメソッドをウォームアップするための短いウォームアップルーチンを実行して作成することです。

于 2012-07-25T14:56:55.357 に答える
2

私の記憶が正しければ、JITでコンパイルされたコードのキャッシュと共有が試みられましたが、これは良い考えではないことがわかりました。

一方では、最新のHotSpot JITコンパイラーは、現在のCPUモデル、および現在の実行の使用パターンのコンテキストでコードを生成および最適化します。コンパイルされたコードをキャッシュする場合、コードが最適でない可能性が高くなります。

一方で、明らかにさまざまなトリックの技術的な問題があります。たとえば、キャッシュされたコードは潜在的なセキュリティホールになります。たとえば、コード領域は、それを共有するすべてのアプリケーション/ユーザーが書き込み可能である必要があります。ただし、これは、あるユーザーが別のユーザーのアプリケーションの実行を妨害する可能性があることを意味します。

于 2012-07-25T15:29:00.877 に答える
2

これは.Net(多くの点でJavaに似ています)に存在し、NGENと呼ばれます。だから私はそれがJavaに存在できなかった理由がわかりません。

私はそれが行われなかった2つの理由を見ることができます:

  • Javaには、.netのアセンブリのような優れたIDメカニズムがありません。しかし、ハッシュは実際に使用できます(jarまたはクラスレベルで)。
  • ほとんどの場合(のみ?)、アプリケーションの起動時にメリットがあります。また、JRE6以降、起動が大幅に高速化されました。
于 2012-07-25T16:55:17.487 に答える
2

一部のJVM(IBMのものなど)には、「事前に共有されたJITコード」があります。(他の回答が指摘しているように)1つのJVMで一度に使用されるクラスファイルは、同じ名前であっても、次回使用されるクラスファイルと同じではない可能性があるため、実行するのは非常に困難です。したがって、「以前に見たクラスAIは、現在のクラスAIと実際に同じである」ことを証明するために必要なロジックがたくさんあります。

もう1つの問題は、JITされたコードにアドレス空間固有の値(たとえば、特定の静的変数のアドレス、または別のJITされたメソッドのエントリポイント)が含まれることが多く、JVMの呼び出しごとに変更される可能性があることです。繰り返しになりますが、これらの問題に対処するには注意が必要です。

AOTコードが提供するパフォーマンスの向上は本物であり、状況に応じてこの機能を使用する価値は非常に高くなります。(具体的には、実行ごとに変更されることはありません。たとえば、同じバージョンのアプリサーバーやEclipseを呼び出すなど)

于 2012-07-26T03:15:46.647 に答える