JVM学習(III):ガベージコレクションアルゴリズム

地域と世代リサイクルアイデアの原則

ときに大学のオペレーティングシステムまたはコンピュータ構成の原則は、地域主義と呼ばれる重要な概念を述べました。

局所性CPUの原理がアクセスすることを意味するメモリアクセス命令を、または、それがデータにアクセスするかどうか、アクセスされたメモリセルは、連続の小領域に集まる傾向にあります。

これは、この原則は、単にローカライズされているメモリキャッシュ(キャッシュ)、アクセス・メモリ(RAM)、ディスク(ROM)について話されていないことが発見されました。実際には、このようなキャッシュメモリキャッシュなど、プロジェクト内のRedisの使用は、また、地域の原則の重要性を反映しています。

ヒープ領域のJava仮想マシンでは、アクティブなオブジェクトは、それのほんの一部になる傾向があり、オブジェクトのほとんどが作成された後に、Java仮想マシン世代回復アルゴリズムの導入を可能にする、数回リサイクルされます。私は、Sunの研究者が地域の原則に触発されていないかわからないが、私は、地域の原理は世代的な思考であることを理解します。

世代の回復は、ヒープの新世代へのスペースと古い時代にあります。新しい世代が新しく作成されたオブジェクトを格納するために使用されます。ときにオブジェクトは、古い時代に移動するのに長い時間を生き延びました。新世代と古い時代の特徴は、Java仮想マシンは、異なる回復アルゴリズムすることができます。

オブジェクトの生存期間の新世代のほとんどは、非常に短い回復時間のかかるアルゴリズムが使用することができ、一般的にマイナーGCと呼ばれるトリガGCの新世代の非常に短いです。

ガベージコレクションと古い時代の頻度が高くないので、古い時代には、多くの場合、長期間生き残ることができるオブジェクト、多くの場合、時間が不足し、古い時代のガベージコレクションのためのスペースをヒープます。しかし、古い時代の回復は多くの時間を消費回復することができるスペースを見つけるために完全なヒープスキャンが通常です。現代のガベージコレクタは、様々な手段によってヒープ全体のスキャンを回避します。GC古いは全GCと呼ばれています。

この記事では、私たちに焦点を当てることは、新世代のためのガベージコレクタで、マイナーGCです。

新世代のメモリパーティショニングと回復のメカニズム

前の上記複製アルゴリズム、彼のアイデアは、ヒープ領域にある1に分割されています。二つの部分に1、および2からポインタを維持します。Java仮想マシンのアクティブなターゲットはごく一部ですので、実際にコピーアルゴリズムを維持する必要がないように、1:1の比率(会社によって与えられた理論的に日はオブジェクトの98%は、わずか数で回収されています)。私たちの予測によると、新世代のコピーアルゴリズムを使用して、オブジェクトのほとんどの死になることを前提としては、効果は非常に良いだろうデータレプリケーションアルゴリズムの少量しか必要とします。こうして新しい世代は、二つのゾーンとエデンサバイバー領域同じサイズに分割されています。

サバイバー領域のデフォルトサイズは、自動的に調整されても、手動で調整することができます。なお、より多くの生存者に割り当てられたメモリ領域、ヒープ空間の使用の効率より低いです。

image.png

私たちは新しい命令を使用する場合は、新しい命令がエデンエリアにオブジェクトを格納するためのメモリとして切り開かれます。新しいエデンエリアは新しいオブジェクトの完全である場合には、この時間はマイナーGCをトリガします。マイナーGC生き残ったオブジェクトは、サバイバーのエリアに移動されます。オブジェクトのJava仮想マシンの記録サバイバー領域は、何度も複製されます。

サバイバーの空の領域へのポインタに、同じように、追いつくために記事の複製アルゴリズムを話します。マイナーGC、エデン領域及びライブオブジェクトが領域からコピーされたときに指摘し、次いでからポインタに切り替えます。次回ように、内容が空であることを確認するためにマイナーGCがあります。

古いプロモーションの機会は何ですか

古い時代に昇格するオブジェクトの新しい世代を作るために2つのケースがあります。最初は、オブジェクトのコピー数が設定値に到達します。オブジェクトが15回(デフォルトは15で、使用することができますコピーされた場合は-XX:+MaxTenuringThreshold修正するために)、このオブジェクトは、古い時代に昇格されます。サバイバー秒が50%以上で占められている(使用可能な-XX:TargetSurvivorRatio、仮想コピーは、古い時代の大きな数値にオブジェクトをコピーして変更する場合)。

マイナーGCはヒープ全体のスキャンを避ける方法

私たちは、しかし、古いオブジェクトの可能なオブジェクトの新しい世代を参照するには、GCのルーツの新世代は、ときにのみマイナーGCスキャンすることを願っています。私たちが期待することはできません。この場合には、そのマイナーGC参照が考慮されなければならないときにオブジェクト、内部GCのルーツに参加する古い参照年の新世代の新世代に歳。あなたは、それはまだ全体のヒープのスキャンと同じではありませんが、古い時代をスキャンするGCの新世代のことがわかりますか?

HotSpot仮想マシンは、この問題を解決するためにカードテーブル(カード表)技術を使用しています。具体的な操作は、512バイトのカードにJava仮想マシン全体のスタックであり、各カードの識別ビットを格納するためのテーブルを維持します。カードの代わりにフラグがオブジェクトの新しい世代への参照が含まれています。あなたはこのカードがあると思うなら、それは汚れています。

マイナーGCあなたはヒープ全体をスキャンすることはできませんが、中にGCのルーツに追加カードテーブルと汚れたカードオブジェクトから汚れたカードを見つけるためにする場合。カードスキャン空フラグのダーティ終了後。

書き込みバリア(書き込みバリア)

説明のアクチュエータでは、Java仮想マシンは、各更新の操作が挙げられる傍受する必要があり、位置に対応するフラグがダーティとマーク。これは、カードオブジェクトの各新しい世代がにマークされていることを保証するために指し示すことができます。
しかし、コンパイラによって生成されたインスタントマシンコードで、コードの一部は、Java仮想マシンの管理下にありません。だから、このコードの一部は、あなたは書き込みバリアと呼ばれる追加のロジックを挿入する必要があります。
書き込みバリアは、新世代へのオブジェクトポイントかどうかを判断することはありませんが、この領域は新しい世代を指摘していることを信じること。これは、1つの単純なシフト操作に命令を簡素化します。書き込みバリアは、パフォーマンスコストをもたらしたが、それはマイナーGCのスループットを増加したものの。したがって、これらのコストは、それだけの価値があります。

仮想共有(偽の共有)

CPUキャッシュラインサイズは64枚のカードの合計を表すカードエントリ(1バイト)ので、64バイトであると仮定する。HotSpotの各カードページがキャッシュラインは64カードページ64 * 512 = 32キロバイトの合計に対応し、512バイトです。
同じキャッシュラインにつながるちょうど同じ32キロバイト領域内に位置するオブジェクト参照更新動作の異なるスレッドが、同時にライトバック・キャッシュ・ラインを発生させる、カードテーブルを更新する場合、プログラムのパフォーマンスの間接的な影響を無効化または同期動作。
ホットスポットは、新しいパラメータを導入し-XX:+UseCondCardMark、オペレーティング・ライト・カードの表を低減することができます。書き込みバリアを実行する前に、最初の裁判官は、単純な何かをします。カードはページを識別された場合には、もはや識別されないこと。擬似コードは次のよう:

if (CARD_TABLE [this address >> 9] != 0)
  CARD_TABLE [this address >> 9] = 0;

概要

ここ要約すると、地域の原則から、この逸脱は、Java仮想マシン世代リサイクルアイデアを上げます。世代回収手段は、ヒープメモリは、古いものと新しい世代の、および異なるガベージコレクションのアルゴリズムに分かれています。

前記新世代は、二つのゾーンエデンサバイバー領域同じサイズに分割されています。GCの新世代はマイナーGCになります。エデンからマイナーGCのタイムゾーンとライブオブジェクトは、サバイバーゾーンはサバイバーゾーンポイントに保存されます指摘しました。スペースの使用の特定のコピー数または値サバイバーエリアの対象サバイバー領域が一定値を超えると、オブジェクトは古い時代に昇格されます。

オブジェクトのマイナーGCのために発生する可能性のある古い問題は、オブジェクト参照の新世代を含め、ホットスポットの仮想マシンは、カードテーブルを解決するための技術を使用することです。

参考記事

JVMカードテーブル(カード表)
鄭ゆうディ:徹底的な解体仮想マシン
Java仮想マシンの-depth理解:JVMの高度な機能とベストプラクティス

おすすめ

転載: www.cnblogs.com/rever/p/11433109.html