1.ガベージコレクションの概要
プログラムを実行するとともに、生成したオブジェクトプログラムがなり、より多くの、メモリシステムは限られているので、オブジェクトはプログラムでクリアされていない一方で、長期安定動作の鍵となります。
ガベージコレクションは、3つの問題に焦点を当てて
どのようなオブジェクトは?リサイクルする必要がある
オブジェクトが参照されなくなったときにもちろん、オブジェクトは役に立たないのではありません、我々は、オブジェクトが回収されるべきであると信じています。オブジェクトがまだ引用されているかどうかを確認する方法、詳細については後述します。オブジェクトが何時?にリサイクルされなければならない
GCを起動するために適切な時期を選択する方法、変更されている動作中のプログラム、オブジェクトが参照されている関係、それはまた、後に詳述する重要な問題です。回復する必要がありますか?
私たちが知っている場合は、不要なオブジェクトを削除する便利なオブジェクトを保持するためにどのようにオブジェクト、後に役に立たない、ガベージコレクションのアルゴリズムは、主要な関心事となり、次のセクションで詳述します。
2.オブジェクトが参照されているかどうかを判断
オブジェクトが参照されているかどうかを判断するには、2つの方法があります。
- 参照カウンタメソッド
名は、カウンタが、各オブジェクトのオブジェクトが参照が破壊され、プログラムカウンタ+ 1、カウンタ-1、0カウンタ値が、オブジェクトが役に立たない場合によって参照されるたびに定義される、を意味する。
この方法一つの欠点は、それぞれの問題は、オブジェクト間で解決できないという基準である。
等:objA.instance = objB; objB.instance = OBJA 、
2つのオブジェクトが回復することができません。
- 到達可能性分析の
目的は、ストランドがそれを達することができる参照していない場合、呼ばれる参照のチェインを通る経路を見つけるために、参照が下方ルックアップで、ルートノードの数(GCルーツ)オブジェクトを選択するために、それは不要なオブジェクトである。よう図に示すように。
GCRootオブジェクトへの参照。
オブジェクトへのオブジェクトBへの参照。
次にA、Bは、オブジェクトを回復することはできません。
3. GCを起動するための適切な時間を選択
- プログラムが実行されているので、参照関係のオブジェクトが変更されたので、私たちは始めるために(世界を停止)実行を停止するために、すべてのスレッドを待つ必要があります。
- JVM GCを調製する前に、フラグがtrueに設定されているされ、各スレッドは、このフラグをチェックするには、真であることが判明した場合、ダウン実行を停止し、GCなどのオブジェクトの現在のスレッドスタック(ローカル変数)を参照にルーツは、参照のチェーンを下に見て、そしてoopMapに保存されています。
注意:オブジェクトがGCのルーツとして使用することができますか?
- 静的変数
- 定数
- スレッド・スタックの参照(ローカル変数)の参照オブジェクト
- スレッドがフラグをチェックするために行ったあたりに使用すると、1つの命令を実行すると、明らかにあまりにも無駄な場合、到達可能性解析を開始する前に、いくつかの場所を通すためにいくつかの手順を手放す、これらの場所は、安全なポイントと呼ばれています。
注意:一般的に指して安全位置として?
- メソッドの戻り値の後
- シングルサイクル終了後
- キャッチする前にジャンプする異常な準備ができて。
- スレッドがスリープ()である場合には、参照関係は変化しません、セキュリティゾーンと呼ばれるこの時間は。スレッドが安全な領域に入ると効果が同じである安全な地点に行ってきました。スレッドスリープ()最後、最初に渡しますフラグは、GCの終わりには、それが待機し続ける終わらないかどうかを判断します。
4.その他
- オブジェクトが起動していない場合は、再利用されるのを避けるために、どのように?
した後、ファイナライズを()を実装し、唯一つの実行ファイナライズ()は脱出する機会を取り戻すために、一般的にはお勧めできません。
public class FinalizeEscapeGC {
public static FinalizeEscapeGC SAVE_HOOK = null;
public void isAlive() {
System.out.println("对象仍然活着!!!");
}
protected void finalize() throws Throwable {
super.finalize();
System.out.println("finalize()方法被执行!!!");
FinalizeEscapeGC.SAVE_HOOK = this;
}
public static void main(String[] args) throws Throwable {
new FinalizeEscapeGC(); // 对象被创建
SAVE_HOOK = null;
System.gc(); // 回收,会执行finalize()
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isAlive();
} else {
System.out.println("对象已死!!!");
}
SAVE_HOOK = null;
System.gc(); // 回收,finalize()已经被执行过,不会再被执行
Thread.sleep(500);
if (SAVE_HOOK != null) {
SAVE_HOOK.isAlive();
} else {
System.out.println("对象已死!!!");
}
}
}
finalize()方法被执行!!!
对象仍然活着!!!
对象已死!!!
- 参照についての
参照型は、他のメモリアドレスに格納されたデータである場合、基準となるオブジェクトの基準時間は、
強度の程度に応じて、ソフト、弱、基準ファントム参照を挙げ強い参照に分割することができます。
1.強い参照
Object obj = new Object();
空のスタックフレームがない限り、強い参照がさえイベントOOMで、GCではありません。
2.ソフト参照
Object obj = new Object();
SoftReference<Object> sf = new SoftReference<Object>(obj);
obj = null;
sf.get();//有时候会返回null
メモリのうち、どのように(GETを介して取得、発生したときにメモリが十分にあるとき、ソフト参照)がリサイクルされます。
ソフト参照は、多くの場合、キャッシュを実装するために使用されています。
3.弱参照
Object obj = new Object();
WeakReference<Object> wf = new WeakReference<Object>(obj);
obj = null;
wf.get();//有时候会返回null
wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收
弱参照は、メモリが十分であっても、第二のごみリサイクルである。データに対応する短い弱参照を取ることによって、行われる第2のガーベッジコレクションがnullを返す場合、取られるべき
4.ファントム参照
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj);
obj=null;
pf.get();//永远返回null
pf.isEnQueued();//返回是否从内存中已经删除
ガベージコレクションは、仮想的な基準が回収された場合、それは同じを参照していません。
- ガベージコレクション面積のメソッド
ガベージコレクションヒープのメインエリアが、ガベージコレクションは、同じようにエリアを発生します。若い世代のための回復時間は、スペースの95%に70%を回復することができますが、恒久的な世代の回収効率がはるかに低いです。
常設廃棄物の定数クラスを目的とした世代のガベージコレクションおよび処分。
一定の放棄
あなたが任意の参照を持っていない場合は、「ABC」のような、そしてリサイクル。
クラス廃棄物
:廃棄物のカテゴリのリサイクルは、三つの条件で満足する必要がある
クラスのすべてのインスタンスが1回復してきた
2 ClassLoaderクラスが回収された
オブジェクトに対応する3のjava.lang.Classクラスをせずにどこでも参照されています
注:クラスは、パラメータ-Xnoclassgcによって回収するかどうかを設定することができます。
大型反射、動的プロキシの数、等CGLIBバイトコードフレーム、および動的に生成されたJSP OSGiのような頻繁の使用に
カスタムクラスローダシーンクラス仮想マシンは永久代わっがオーバーフローしないようにするために、機能をアンロードする必要がある含みます。