アウトライン
スレッドが生まれ、スレッド、メモリの割り当てと確実に装備されているこれらの領域の回復で死亡したとJavaランタイムエリア、プログラムカウンタ、仮想マシン・スタックは、ネイティブメソッドは、多くの考えを必要としない、三つの領域をスタックリサイクルの問題。Javaヒープおよびメソッド領域は、複数のブランチの方法は、メモリの必要性ではないかもしれない必要なメモリのインタフェースを実装するクラスのより多くが、同じではありません、我々は唯一のオブジェクトが作成されます知るために実行することができ、同じではありません、メモリの割り当てとガベージコレクタのこの部分の回復が懸念されます。ガベージコレクタは、3つの問題に完了する必要があります。そのメモリを再利用する必要性を、いつ、どのようにリサイクルをリサイクルします。
回収されることを拒否する人たち
ガベージコレクションの基本的な考え方は、あなたが、そのオブジェクトは逆に、使用されていることができれば、あなたはこのオブジェクトにアクセスすることができ、ルートから開始しているオブジェクトのアップは、オブジェクトへのルートからアクセスすることはできません検討することである、オブジェクトが説明されていますもはや使用されている、一般的には、オブジェクトが回復されるべきではありません。このアルゴリズムは、ルート検索アルゴリズムです。
到達可能性解析
しかし実際には、可能な目標到達不能「復活」一定の条件の下で自分自身なので、その回復は無理があります。この目的のために、我々は、オブジェクトの到達可能性の状態、および状態が安全にオブジェクトを再利用することができ、その下の規定の定義を与えます。アクセシビリティオブジェクトは、次の3つの状態が含まれています。
- 到達可能な:あなたはこのオブジェクトを検索することができ、参照ノードに応じて、ルートから始まります
- 復活する:オブジェクトへのすべての参照が解放されているが、オブジェクトがあり
finalize()
、独自のメソッドを復活させます。 - 到達不能:オブジェクトの
finalize()
メソッドが呼び出され、そして、その後、到達不能入力して提起されていません。ので、到達不能オブジェクトは、「復活」することができないfinalize()
方法を一度だけ呼び出すことができます。
/**
*
* <p>Description: 1.对象被GC时,可以通过finalize拯救 2.finalize只被调用一次 </p>
* @date 2019年8月25日
* @version 1.0
*/
public class FinalizeTest {
private static FinalizeTest currentObj;
@Override
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize invoke");
//重新引用
currentObj = this;
}
public void alive() {
System.out.println("live");
}
public static void main(String[] args) throws InterruptedException {
currentObj = new FinalizeTest();
currentObj = null;
System.gc();
//finalize优先级地,先等待
Thread.sleep(500);
if(currentObj == null) {
System.out.println("dead");
}else {
currentObj.alive();
}
currentObj = null;
System.gc();
//finalize优先级地,先等待
Thread.sleep(500);
if(currentObj == null) {
System.out.println("dead");
}else {
currentObj.alive();
}
}
}
上記のコードは、コードフラグメントとして破壊が、結果は同じで、最初のオブジェクト「レスキュー復活」成功、別の障害はありませんでしたが、それが正常に再利用することができます。
次のカテゴリのGCのルーツとして:
- 仮想マシンのスタック(ローカル表スケールのスタックフレーム)の参照オブジェクト
- 領域によって参照されるメソッド静的プロパティクラスオブジェクト
- 一定の基準物体領域の方法
- JNIネイティブメソッドスタック参照(すなわち、プロセス一般ネイティブ)オブジェクト
参照型の4種類
JDK1.2への参照が強い参照、ソフト参照、弱参照、ファントム参照四種類に拡大した後、これら四つの強度が一旦弱め。拡張を参照することで、メモリ使用量などのオブジェクトの観点から説明することができます。十分なメモリがメモリに保持されている場合、ガベージコレクションのためのメモリ空間はまだ非常にタイトである場合は、オブジェクトのこのタイプを破棄することができます。多くのシステム・キャッシング機能は、このようなシナリオに対応します。
強い参照
Javaでは、最も一般的なオブジェクトが変数への参照が割り当てられ、強い参照で、参照変数は強い参照です。オブジェクトは強い参照変数の参照である場合には、それは状態次第で、将来的には、オブジェクトがJVMが収集されることはありません使用されることはありません場合でも、ガベージコレクションのメカニズムをリサイクルすることはほとんどありません。だから、強い参照が主な原因のJavaメモリリークの一つです。ソフト参照
ソフト参照は、唯一のソフト参照の対象に実装するSoftReferenceクラスを必要とするシステムメモリが十分にあるとき、不十分なシステムメモリ空間があるとき、それはリサイクルされます、回復されることはありません。ソフト参照は通常、メモリを大量に消費するプログラムのために使用されています。
弱参照
弱い参照クラスに必要な弱参照は、占有物の回収率が常にある、それは関係なく、JVMのメモリの、ガーベッジコレクション動作する限り、オブジェクトに短く、のみ弱参照よりも柔らかいの寿命を指し、十分ではありません、実装しますメモリ。
偽の引用
達成するために必要なPhantomReferenceクラスの仮想基準、それは単独で使用することができず、参照キューは、組み合わせて使用する必要があります。仮想基準の主な役割は、オブジェクトを追跡することであるガベージコレクト状態です。
場合でも回復
トリガ条件のシリアルGCのHotSpot VMのビューの実現は、以下のカテゴリに分類されます。
- 若いGC:エデンのフル割り当てトリガの若い世代エリア。若いGCライブオブジェクトの一部は、古い世代に昇格されますので、若いGC古い足跡世代は、一般的に増加されることに注意してください。
- フルGC:統計が(HotSpot VMのため、古い世代はGCは若いトリガーが、トリガーフルGCをオンにしないであろうよりも、現在の大規模な余剰スペースのGCのプロモーションの若い平均サイズを言う前に、それが発見された場合は、一度若いGCをトリガする準備ができていますGC、同時収集CMSの添加により、古い世代を収集するために、他のは若い世代を含め、GC GCスタック全体で同時に収集され、)別々の事前ヤングGCをトリガする必要はありません。あるいは、それはパーマ世代を持っている場合、パーマ世代に領域を割り当てるが、十分なスペースがないですが、また、フルGCをトリガするために、またはにSystem.gc()、GCとのヒープダンプ、デフォルトはフルGCをトリガされます。
一部では、複雑なトリガ条件が、一般原則として、実際にHotSpot VMの他の非同時GCは、同じことを言います。並行GC条件は同じではありませんトリガされます。CMS GCに、例えば、それは比率がトリガーを超えた場合、古い世代の使用のタイミングを確認するために主にCMS GC、行うには、古い世代の同時収集を開始します。
リサイクルする方法
ガベージコレクションのアルゴリズムに関連する主にリサイクルする方法。ここではいくつかのアイデアのガベージコレクションのアルゴリズムがあります。
メソッド明確なマーク(マークスイープ)
クリアラベル付けアルゴリズムは、近代的なガベージコレクションアルゴリズムの思想的基盤です。相はマーキングおよびクリアランス相:それは2つの段階に分けられます。マークフェーズにおいて、最初のルートによって、全てが、ルートから到達可能なチームオブジェクトガーベッジオブジェクトしたがって、オブジェクトが参照されていないとマークされていないマーキング。そして、クリーンアップの段階で、すべてのオブジェクトがマークされていません削除します。
明確なラベリングアルゴリズムの欠如は、以下のとおりです。効率性と明確な標識後に生じる不連続なメモリの断片化の問題の数が多いです。そして、あまりにも多くの連続したメモリを見つけることができない、大きなオブジェクトの割り当てでメモリの断片化につながり、事前に別のガベージコレクションをトリガしなければならなかったことがあります。
レプリケーションアルゴリズム(対処)
核となるアイデアは、アルゴリズムをコピーすることである:元のメモリ空間を2つに分割され、ガベージコレクションは、メモリは、未使用のブロックの後に使用されているオブジェクトがある、メモリ内の各のみ生存コピーがクリアされメモリブロックで使用されるすべてのオブジェクトは、二つのメモリスイッチの役割は、ガベージコレクションが完了しています。
オブジェクトは、多くのシステムで回収される場合、アルゴリズムはコピーライブオブジェクトを複製する必要のあるレプリケーションアルゴリズムの効率が高くなり、比較的小さな、リアルタイムガベージコレクションになります。そして、オブジェクトが新しいメモリ空間にコピーされた統一ガベージコレクションのプロセスであり、その後、元の使用のメモリをクリアするので、あなたは、メモリ空間の回復が全く破片ではないことを確認することができます。しかし一方で、アルゴリズムのコピーのコストはより多くのメモリ空間を使用する必要があります。
レプリケーションアルゴリズムは、新世代のために、より適しています。不要なゴミオブジェクトの新しい世代は、通常のオブジェクトを生きているので、効率的な複製アルゴリズムが高くなります。
アルゴリズム(マーク・コンパクト)を整理するタグ
古い時代には、オブジェクトのほとんどはライブオブジェクトです。あなたはまだ対象の生存とよりによるコピーアルゴリズムを使用している場合、また、コピーのコストが増加します。そのため、古い時代の特性に基づいてガベージコレクションは、他のアルゴリズムを使用する必要があります。回復アルゴリズムを整理するタグは、アルゴリズム歳。これは、マークに基づいていくつかの最適化アルゴリズムを作りました。そしてそれはまた、最初から複数のノードであるとして、ラベル付けアルゴリズムをクリア、それは、オブジェクトがマークされますが、メモリ圧縮の側にオブジェクトの生存、境界の外側のすべてのスペースをクリアした後にされていないクリアされていません。この方法は、破片の生成を回避するだけでなく、あまりにも多くのメモリ空間を必要としないので、コストが比較的高いです。
最終的な効果は、アルゴリズムの実行が完了した後にクリアフラグをマーキングし、次にメモリの断片化を終え、したがって、それが明確な仕上げマーカー(MarkSweepComact)と呼ぶことができるの配置方法と等価です。
世代アルゴリズム(世代別収集)
世代アルゴリズムは、メモリ生きているサイクルに、いくつかの異なるオブジェクトに基づいています。あなたは、各時代の特徴に応じて最も適切なアルゴリズムを収集できるように、Javaヒープは、一般的に、古いものと新しい世代のに分かれています。新しい世代が死んだ夜の学生に向けたオブジェクトによって特徴づけられる、新しいオブジェクトの約90%が回収され、複製アルゴリズムの新世代に適します。いくつかはまだ生きているの後にオブジェクトが回収された場合、オブジェクトは、古い時代のメモリに配置されます。古い時代には永久的なメモリである、あなたは整理するためにタグを使用し、明確なラベリングアルゴリズム歳のできる、でも、プログラムのライフサイクル全体を通して、時間をかけて対象物とみなすことができます。
年新世代と旧のために、回復の新世代は、通常、非常に高い周波数であるが、それぞれの時間が非常に短い回復時間がかかり、かつリサイクル古いが比較的低い周波数ですが、より多くの時間を消費します。
パーティションアルゴリズム(地域)
一般的には、同じ条件の下で、ヒープ大きい、GCイベントのために必要な時間は長く、長い一時停止が発生したので。より良好な大きなメモリ領域の意志によって、滞留時間のために休止時間の目標に従って、単に複数のサイズのような小さな領域に分割され、それぞれがそれによって時間GCを低減する、いくつかの小さな間隔、全体ではなくヒープ領域を回収しました一時停止が発生しました。分割アルゴリズムは、連続する異なるセル間の全体のヒープ領域に分割されています。独立して、各セル間の独立回復。