パフォーマンスに対するJVMエスケープ分析の影響

エスケープ分析の基本的な動作は、オブジェクトの動的スコープを分析することです。オブジェクトがメソッドで定義されると、メソッドエスケープと呼ばれる外部メソッドによって参照される場合があります。スレッドエスケープと呼ばれる他のスレッドでアクセスできるクラス変数またはインスタンス変数への割り当てなど、外部スレッドからもアクセスできます。

エスケープいくつかの方法の方法を次のように

パブリッククラスEscapeTest {
    パブリック静的オブジェクトOBJを、
    公共ボイドglobalVariableEscape(){//グローバル変数への代入、脱出の発生
        OBJ =新しい新しいオブジェクト();
    }
    公共methodEscapeオブジェクト(){//復帰方法値は、エスケープの発生
        戻り新しい新しいオブジェクト();
    }
    公共ボイドinstanceEscape(){//例参照が逃げる発生
        試験(本);
    }
}

スタック上に割り当てられ
、割り当てプロセス変数であり、スタック上に割り当てられ、スタック、方法上のオブジェクト実行が完了すると、ガベージコレクションの介入なしに自動的に破棄され、システムのパフォーマンスが向上します。

同期により、
スレッドの同期自体が不要になり、コストが高くなります。オブジェクトがスレッドをエスケープせず、他のスレッドからアクセスできないと判断した場合は、オブジェクトの読み取りと書き込みの競合が発生しないため、この変数の同期対策を不要にできます。シングルスレッドではロックの競合はありません。(ロック内のオブジェクトとロックブロックはスレッドをエスケープできなくなり、同期ブロックはキャンセルされます。)

スカラー置換
Java仮想マシンのプリミティブデータ型(int、long、その他の数値型、参照型など)は、さらに分解することはできず、スカラーと呼ぶことができます。逆に、データの一部を分解し続けることができる場合、それは集約と呼ばれ、Javaで最も一般的な集約はオブジェクトです。エスケープ分析により、オブジェクトが外部からアクセスされないことが証明され、このオブジェクトが分解可能である場合、プログラムが実際に実行されても、このオブジェクトは作成されず、このメソッドで使用されるいくつかのメンバー変数が直接作成されます。代わりに。逆アセンブルされた変数は個別に分析および最適化
できスペースはスタックフレームまたはレジスターに個別に割り当てることができ、元のオブジェクトは全体としてスペースを割り当てる必要はありません。

オンスタック割り当ての詳細分析
public class OnStackTest {
    public static void alloc(){
        byte [] b = new byte [2];
        b [0] = 1;
    }
    public static void main(String [] args){
        long b = System .currentTimeMillis();
        for(int i = 0; i <100000000; i ++){
            alloc();
        }
        long e = System.currentTimeMillis();
        System.out.println(eb);
    }
}

-XX:+ DoEscapeAnalysisはエスケープ分析を有効にします(デフォルトではjdk1.8が有効になっており、他のバージョンはテストされていません)
-XX:-DoEscapeAnalysisエスケープ分析を無効にしてエスケープ分析を

有効にします。実行時間は4ミリ秒です。以下に示すように


、エスケープ分析をオフにすると、実行時間は618ミリ秒になり、GCログ情報がたくさんあります。以下に示すように:


**エスケープ分析は、上記によってオンとオフが切り替えられます。エスケープ分析がオンの場合
、オブジェクトはヒープに割り当てられず、GCは実行されませんが、オブジェクトはスタックに割り当てられます。
エスケープ分析をオフにすると、すべてのオブジェクトがヒープに割り当てられます。ヒープ内のオブジェクトがいっぱいになると、複数のGCが実行され、実行時間が大幅に長くなります。ヒープ上の割り当ては、スタック上の割り当てより数百倍遅いです。**

ジャストインタイムコンパイル(JIT)
1.クライアントコンパイラを使用する場合、デフォルトの実行はホットコードと見なされる前に1500回です
。2。サーバーコンパイラを使用する場合、デフォルトの実行はそれが見なされる前に10000回です。ホットコード:
上記の例でエスケープ分析をオンにした後、すべてのオブジェクトがスタックに直接割り当てられるわけではありませんが、このコードはJIT分析によるホットコードであり、非同期コンパイルはローカルマシンコードにコンパイルされ、オブジェクトはエスケープ分析によって分析されます。スタックに割り当てられます。(コンパイラサーバ場合は10000サイクルおよび時間、オブジェクトはヒープ上に割り当てられていることをネイティブマシンコードにコンパイルされたネイティブマシンコードにコンパイルされたオブジェクト前にスタックに割り当てられる)

+開口スカラーEliminateAllocations:-XX置換(jdk1.8はデフォルトで有効になっており、他のバージョンはテストされていません)
-XX:-EliminateAllocationsスカラー置換をオフにします。
スカラー置換はエスケープの分析に基づいています。スカラー置換をオンにします。エスケープ分析を

オンにし、スカラー置換をオフにします

今回は、エスケープ分析をオンにし、スカラー置換関数をオフにしたところ、オブジェクトがヒープに再度割り当てられ、複数のGCを実行したことがわかりました。このことから、javaは実際のスタック割り当てを実装しておらず、スタック割り当てを実現するためのスカラー置換を実装していることがわかります。

ロック解除の詳細な分析により
、上記のOnStackTestコードがわずかに変更され、同期ブロックが追加されました。64を超えるデフォルトの配列長はスタックに割り当てられないため、ロックの削除の影響をテストする例として、ヒープへの割り当てを使用します。

public class OnStackTest {
    public static void alloc(){
        byte [] b = new byte [65];
        synchronized(b){//同期コードブロック
            b [0] = 1;
        }
    }
    public static void main(String [] args )throws IOException {
        long b = System.currentTimeMillis();
        for(int i = 0; i <100000000; i ++){
            alloc();
        }
        long e = System.currentTimeMillis();
        System.out.println(eb);
    }
}

-XX:+ EliminateLocksオープンロックの除去(jdk1.8は、他のバージョンでテストされていない、デフォルトで有効)
-XX:-EliminateLocksは排除ロック閉じた
ロックは、エスケープの分析に基づいてオープンする必要がなくなり、エスケープ分析は、ロックを開いて排除する

排除するためにロックを開くために

、閉じたロックの除去を


オープンロック解消実行時間は1807ミリ秒、
クローズロック解消実行時間は3801ミリ秒で
あり、ロック解消を開閉することで性能が2倍以上になっていることがわかります。

おすすめ

転載: www.cnblogs.com/zhuyeshen/p/12735782.html