さいしゅうじかんさいてきか

3877 ワード

JIT:Javaプログラムは、最初は解釈器で実行されていましたが、仮想マシンがメソッドやコードブロックの実行が特に頻繁であることを発見すると、これらの「ホットスポットコード」をマシンコードにコンパイルし、実行効率を高めます.

1.なぜインタプリタとコンパイラを併用するのですか?

  • プログラムの迅速な起動と実行が必要な場合、解釈器を使用してコンパイル時間を節約し、すぐに実行することができます.時間が経つにつれて、コンパイラは次第に役割を果たし、マシンコードにコンパイルされ、効率を高めることができる.
  • メモリ制限が大きい場合、解釈器実行はメモリを節約し、逆にコンパイラ実行は効率を向上させることができる.
  • 解釈器は、コンパイラが急進的に最適化された脱出ゲートとして機能することができる.

  • 2.HotSpotの2つの異なるインスタントコンパイラ

  • Client Compiler:C 1コンパイラ
  • Server Complier:C 2コンパイラ
  • interpreted mode:純解釈モード
  • compiled mode:純粋なコンパイルモードで、コンパイルできないのは解釈器なのか介入するのか
  • mixed mode:解釈器とコンパイラの組み合わせ
  • 最適化度の高いコードをコンパイルするには時間コストがかかるため,仮想マシンはバランスをとるために階層コンパイルを採用している.階層型コンパイルを採用すると、C 1とC 2が同時に動作し、C 1はより高いコンパイル速度を得、C 2はより良いコンパイル品質を得る.
  • 第0層:プログラム解釈実行、解釈器は性能監視を開かず、第1層コンパイルをトリガーすることができる.
  • 第1層:C 1コンパイル、簡単で信頼性の高い最適化、必要に応じて性能モニタリングを加える.
  • 階層:コンパイルに時間がかかる最適化を開始し、パフォーマンスモニタリング情報に基づいて信頼性の低い急進的な最適化を行うこともできます.

  • 3.コンパイル対象とトリガ条件


    ホットスポットコード:
  • 複数回呼び出されるメソッド:メソッド全体がコンパイル対象であり、仮想マシン標準のJITコンパイル方式である.
  • が複数回実行される循環体.メソッドの実行中にメソッドフレームがスタックに存在するため、メソッド全体がコンパイル対象となります.このコンパイルはスタックに置き換えられます.

  • ホットスポットの検出:
  • サンプリングに基づくホットスポットプローブ:仮想マシンは各スレッドのスタックトップを周期的にチェックし、ある方法がスタックトップによく現れる場合は、ホットスポットであることを示します.利点:単純で効率的で、メソッド呼び出し関係を容易に取得できます.欠点:1つの方法の熱を正確に確認することが難しく、スレッドのブロックや他の干渉を受けやすい.
  • カウンタのホットスポット検出に基づく:仮想マシンは各方法、さらにはコードブロックにカウンタを確立し、方法の実行回数を統計する.利点:正確.短所:コストが高い.

  • HotSpotは2つ目の方法を使用しています.メソッド呼び出しカウンタとエッジバックカウンタの2種類があります.
    メソッド呼び出しカウンタ:メソッドが呼び出された回数を統計します.デフォルトのしきい値Clientは1500回、Serverは10000回です.
    何も設定しない場合、メソッド呼び出しカウンタはメソッド呼び出しの絶対回数ではなく、一定時間を超えるとカウンタが半減します.この減衰は実GCのついでに行われる.-X:CounterDecayで減衰するかどうかを設定できます.減衰しない場合は、時間が経つにつれて、常に回数に達してコンパイルされます.
    エッジカウンタ:メソッド内のループの実行回数を統計します.正確にはエッジバック回数で、空のループはエッジに戻らず、自分だけにジャンプします.Clientモードしきい値:メソッド呼び出しカウンタしきい値OSR比率/100、OSR比率デフォルト933.serverモードしきい値:メソッド呼び出しカウンタしきい値(OSR比率-解釈器モニタ比率)/100、OSR比率デフォルト140、解釈器モニタ比率デフォルト33.
    エッジカウンタに熱減衰はありません.

    4.いくつかのコンパイル技術

  • 言語に関係のない古典的な最適化技術の1つ:共通サブエクスプレッションの除去.
  • 言語に関連する古典的な最適化技術の1つ:配列範囲チェック除去.
  • の最も重要な最適化技術の1つ:方法のインライン.
  • 最先端の最適化技術の一つ:脱出分析.

  • 共通サブエクスプレッション消去:1つのエクスプレッションが前に計算され、後のエクスプレッションの変数も変化していない場合、このエクスプレッションが共通サブエクスプレッションであるため、計算する必要はありません.
    //javac , JIT b * c
    int d = (c * b) * 12 + a + +(a + b * c)
    

    配列境界チェック消去:Javaは配列要素にアクセスすると自動的に上下境界の範囲チェックを行い、境界を越えるとArrayIndexOutOfBoundsExceptionを放出しますが、これもパフォーマンスの負担です.仮想マシンは、状況に応じてコンパイラが境界を越える可能性があるかどうかを判断し、境界を越えて実行しない場合はチェックする必要はありません.同様にNull PointException、除数0異常などもある.
    メソッドインライン:コンパイラの最も重要な最適化手段の一つであり、メソッド呼び出しのコストを排除し、他の最適化の基礎を構築した.
  • メソッドのインラインはコードレプリケーションほど簡単ではありません.Javaメソッド(コンパイル期間解析を除く)では、コンパイル期間がバージョンを特定できないため、実行期間が可能です.この問題を解決するには、タイプ継承関係解析CHAを使用します.

  • タイプ継承関係解析CHA:アプリケーション全体に基づいて、現在ロードされているクラスのうち、あるインタフェースが1つ以上実装されているかどうか、あるクラスにサブクラスがあるかどうか、サブクラスが抽象クラスであるかどうかなどの情報を決定します.
  • コンパイラがインラインする場合、非ダミーメソッドであれば、直接インラインします.虚メソッドに遭遇した場合、CHAに複数のバージョンがあるかどうかをクエリーし、1つしかない場合は、インラインを行います(急進的で、脱出ゲートが必要です).後続の仮想マシンが他のクラスをロードして継承関係を変更していない場合は、常にインラインされます.そうしないと、解釈ステータスが戻ったり、再コンパイルされたりします.
  • CHAで複数のバージョンがクエリされた場合、コンパイラはインラインキャッシュを使用します.呼び出しが発生しない前に、キャッシュは空で、呼び出しが発生した後、キャッシュはメソッドのバージョン情報を記録し、その後、呼び出しのたびにバージョンを比較し、ずっと、インラインが継続し、一致しない場合は、インラインをキャンセルします.虚メソッドテーブルを検索します.

  • 脱出分析:オブジェクトのダイナミックな役割ドメインを分析します.コード最適化手段ではなく、他の手段に根拠を提供する.
  • メソッドエスケープ:オブジェクトが外部メソッドによって参照される.
  • スレッドエスケープ:クラス変数に値を割り当てるなど、外部スレッドによってオブジェクトがアクセスされます.

  • オブジェクトが逃げないことを証明すれば、いくつかの効率的な最適化が可能になります.
    スタックの割り当て:一般的なオブジェクトはスタックに割り当てられ、各スレッドが共有され、GCでメモリを回収するのに時間がかかります.ローカル変数などのオブジェクトが脱出しない方法を決定した場合、スタックに割り当てるのは快適で、スタックフレームのスタックから出るにつれて破棄することができます.GC圧力減少.
    ≪同期消去|Synchronize Description|emdw≫:オブジェクトがスレッドの脱出ではないと判断した場合、他のスレッドにアクセスされず、競合はなく、同期を完全に解消できます.
    スカラー置換:オブジェクトが外部にアクセスされないと判断した場合、実際に実行するときは、このオブジェクトを作成する必要はありません.スタックにオブジェクトが分割されたスカラーを作成するように変更します.