JITとエスケープ解析

以前に述べたバックエンドコンパイラコンパイラの理論は、このプロセスでは、あなたが解釈され、コンパイル、実行2本の道路を取ることができ、バイト命令プロセスにコンパイル済みのクラスファイルです。

1つの散歩を解釈した場合、メソッドを実行する毎に、再度説明する必要があり、効率に遅くなります

クラスファイル、およびクラスファイルに変換javacのJavaソースファイルは、すべてのJavaバイトコードです。だから、クラスファイル内のJVMは、それらのバイトコード、1つのアウトずつ、このメソッドの実装が解釈される一つ一つのために、後にロードされます。

2.コンパイラは、すべてを実行する場合に行く、そして特殊なメモリ消費、それぞれが再びメソッドをコンパイルするようになった、とメモリに、その後の質問は実行コードコンパイラの低周波がメモリを占有することを、貴重なメモリで、そのようです

もう一つは、CPUが直接実行するように、Javaバイトコードの最適化、生成されたマシンコードを再コンパイルすることです。このシリーズのアウトコードは、より効率的になります。一般的に、私達はちょうど見つけるマシンコードにコンパイルするために最も頻繁に占めるCPU最長の道を呼び出す必要があり、すべてのJavaメソッドをマシンコードにコンパイルされて配置する必要はありません。これは、最も頻繁にJavaメソッドを呼び出した私たちは、多くの場合、ホットメソッド(ホットスポットは、おそらく仮想マシンの名前はここからである)ことを言うことです。この需要はジャスト・タイムにランタイム道にコンパイル。

現在主流の商業のHotSpot仮想マシンが(ジャストインタイム)技術JIT使用することができ、(インタプリタとコンパイラを使用してモードを混在している)混合モードを使用している - 時のコンパイル、JITの導入を、あります効率化とJVMメモリ空間のバランスを見て、コンパイルされた項目の最適化。JITは、コードの最適化の多くを行います。目的は、エスケープ解析と呼ばれる重要な技術であるメモリ割り当てヒープ圧力の最適化、の一部を削減することです。

ナゲッツ1組のエスケープ解析は非常に徹底した記事、運ば言っ参照:juejin.im/post/5b4d47を...

エスケープ解析とは何ですか

基本的なエスケープ分析は、分析対象動的スコープの動作です:オブジェクトがメソッドで定義されている場合、そのような他の場所に渡す呼び出しパラメータなどの外部手段によって参照される、方法が脱出する呼びます。

public static StringBuffer craeteStringBuffer(String s1, String s2) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb;
}

public static String craeteStringBuffer(String s1, String s2) {
    StringBuffer sb = new StringBuffer();
    sb.append(s1);
    sb.append(s2);
    return sb.toString();
}

复制代码

ないエスケープSBコードの第2のセグメントが、脱出する最初のコードSB。

次のようにエスケープ解析を使用して、コンパイラがコードを最適化することができます:

同期は省略します。オブジェクトはオブジェクトのみの動作のために一つのスレッドからその後にアクセスできることが分かっている場合は同期考えることはできません。

第二に、スタックはスタック割り当てに変換しました。オブジェクトは、そのオブジェクトへのポインタを作るために、サブプログラムに割り当てられている場合は逃れることはありません、割当候補オブジェクトをスタックではなくヒープ割り当てよりも、かもしれません。

第三に、分離オブジェクトの交換またはスカラー。メモリ構造の連続的な存在もアクセスすることができるように、いくつかのオブジェクトが必要とされないかもしれない、そのオブジェクトの一部(またはすべて)は、メモリに格納されないかもしれないが、CPUレジスタに格納されています。

JVMパラメータは、エスケープ分析を開くかどうかを指定してJavaコードで実行し、

-XX:+ DoEscapeAnalysis:エスケープ分析に示します

-XX:-DoEscapeAnalysis:手段は、分析を逃れる閉じ

同期が省略されています

一つだけのスレッドが他のスレッドに公開されずにアクセスできる場合は、JDK 1.7から動的コンパイルのシンクブロックスタートは、JITコンパイラを分析から逃れるデフォルトでは、使用されるロックターゲット同期ブロックを判断するために分析を逃れることができました。使用される同期ブロックのロックオブジェクトは、この分析を介してアクセスする唯一のスレッドであることが判明した場合、JITコンパイラは、このシンクブロックをコンパイル時の同期コードのこの部分がキャンセルされます。同期プロセスのキャンセルをも排除ロックとして知られている、同期省略呼ばれます。次のコードのように:

public void f() {
    Object hollis = new Object();
    synchronized(hollis) {
        System.out.println(hollis);
    }
}
复制代码

オブジェクトをロックするホリスコードが、オブジェクトのライフサイクルホリスのみ()メソッドF、およびJITコンパイルフェーズが離れて最適化されるので、他のスレッドによってアクセスすることができません。に最適化されました:

public void f() {
    Object hollis = new Object();
    System.out.println(hollis);
}
复制代码

そのため、同期使用しているとき、および分析を通じてJITエスケープが何のスレッドの安全性の問題を発見した場合は後に、それはロックがなくなるんでしょう。

スカラー交換

スカラー(スカラー)は、もはや小さなデータに分解することができるデータを指します。元のデータ型でJavaはスカラーです。対照的に、これらのデータはまた、Javaは、彼が他の骨材およびスカラー量に分解することができるので、重合の量であるオブジェクト重合(凝集体)の分解量と呼ばれてもよいです。JITの段階では、エスケープ分析後の場合、オブジェクトは、次にJIT最適化を介して、このオブジェクトは、その中に代わりに含まれる複数の変数のメンバーの数に分解され、外部アクセスできないことを見出しました。このプロセスは、スカラーで置き換えられます。

public static void main(String[] args) {
   alloc();
}

private static void alloc() {
   Point point = new Point(1,2);
   System.out.println("point.x="+point.x+"; point.y="+point.y);
}
class Point{
    private int x;
    private int y;
}
复制代码

上記のコードでは、オブジェクトは、点ALLOC方法を逃げない、オブジェクト点はスカラーに分解することができます。だから、JITは直接Pointオブジェクトを作成しますが、2つのスカラーはint xの直接使用する代わりに、Pointオブジェクトのyをint型ではないでしょう。上記のコードは、スカラーを交換した後、次のようになります。

private static void alloc() {
   int x = 1;
   int y = 2;
   System.out.println("point.x="+x+"; point.y="+y);
}
复制代码

エスケープ分析した後、重合ポイントの量を見て、彼は脱出していない、それは二つに重合の量に置き換えられていることがわかります。スカラ交換が、それは良い何ですか?それが大幅にヒープメモリの使用量を減らすことができます。オブジェクトを作成する必要はありません一度ので、それはヒープメモリを割り当てる必要はなくなりました。

スカラ交換は、スタック良い基盤を提供して上に割り当てられています。

スタックに割り当て

Java仮想マシンは、Javaオブジェクトは常識であるヒープメモリ上に確保されています。しかし、エスケープ解析後のオブジェクトは、スタック上に割り当てされるように最適化することができ、方法をエスケープしていないことが判明した場合、ある特別な場合は、そこにあります。これは、ヒープ上のメモリを割り当てる必要がなくなり、ガベージコレクションのアップは必要ありません。

スタックの分布の詳細については、を参照することができるオブジェクトと配列はヒープメモリ上に割り当てられていません

ここでは、まだ、実際には、簡単な何かを言うために、既存の仮想マシンを持って、スタックの真の意味に割り当てられていない、オブジェクトと配列はのヒープメモリ上に割り当てられていない例、オブジェクトはヒープ上に割り当てられていません、実際には、スカラー交換が達成されます。

分析をエスケープも非常に成熟していない1999年に出版され、エスケープ分析上の成熟した論文ではなく、唯一のJDK 1.6の実装、および技術今までに。このため根本的な理由は、パフォーマンスのエスケープ分析は、彼の消費よりも高いを消費することができることを保証するものではありません。した後でも、エスケープ分析は、スカラー交換が行われ、スタック上に割り当てられ、そして排除ロックすることができます。しかし、彼らのエスケープ分析は、分析の複雑なセットを必要とし、それはまた、比較的時間のかかるプロセスです。

極端な例では、オブジェクトが逃げ場を発見していないされていない、脱出後の分析です。それこの分析を逃れるプロセスが無駄になります。技術は非常に成熟していないですが、彼はまた、タイムコンパイラ技術ですが、最適化の非常に重要な手段です。

おすすめ

転載: juejin.im/post/5d36ebdff265da1ba915bf20
おすすめ