ホームページ  >  記事  >  Java  >  Java でのリサイクルされたオブジェクトのマーキングとオブジェクトの二次マーキング プロセスの詳細な説明

Java でのリサイクルされたオブジェクトのマーキングとオブジェクトの二次マーキング プロセスの詳細な説明

黄舟
黄舟オリジナル
2017-10-11 10:12:431709ブラウズ

この記事は主に Java リサイクル オブジェクトのマーキングとオブジェクトの二次マーキング プロセスについて紹介しています。必要な方はここで共有します。

1. オブジェクトのマーキング

1. マークとは何ですか?マークの付け方は?

最初の質問は、ガベージ コレクターの掃除を容易にするために、いくつかの死んだオブジェクトにマークを付けることであることは誰もが知っていると思います。 マークの付け方としては、大きく分けて参照カウントと到達可能性解析の2つの方法があります。

参照カウントの実装は比較的簡単です。オブジェクトへの参照があるたびに、参照カウンターが 1 ずつ増加します。参照が無効な場合は、1 ずつ減少します。カウンタが 0 になると、リサイクル可能としてマークされます。この判断は非常に効率的ですが、多くの主流の仮想マシンはこの方法を使用していません。主な理由は、複数のオブジェクト間の循環参照の問題を解決することが難しいためです。あまり使用されていませんが、それでも学ぶ価値があります。


public class Test {
private Object obj;
Public static void main(){
Test t1=new Test();
Test t2=new Test();
t1.obj=t2;
t2.obj=t1;
t1=null;
t2=null;
//如果对象在这行发生gc,那么t1和t2对象是否能被回收
System.gc();
}
}

到達可能性分析の基本的な考え方は、「GC ルート」と呼ばれるいくつかのオブジェクトを開始点として使用し、これらのノードから検索を開始し、直接または間接的な参照関係を持つオブジェクトを検索します。これらのオブジェクトはチェーンの形で結合され、参照チェーンとも呼ばれる「関係ネットワーク」を形成します。最後に、ガベージ コレクターは、この関係ネットワークにないいくつかのオブジェクトを収集します。図に示すように:

GC Roots オブジェクトに接続されているオブジェクトは確実に生きているオブジェクトであり、右側の die オブジェクトは GCROOTS とは何の関係もないため、リサイクル可能なオブジェクトとしてマークされます。現在、主流の商用仮想マシンは同様の方法を使用しています。では、「GC ルート」として使用できるオブジェクトは何でしょうか? Javaでは「GCルート」として利用できるオブジェクトは4種類あります

1:スタックフレーム内のオブジェクトを参照する(第1章の名詞)。 (スタック内)

2: 静的プロパティによって参照されるオブジェクト。 (メソッド領域内)

3: 定数によって参照されるオブジェクト。 (メソッド領域内)

4: ローカル メソッド スタック内の JNI によって参照されるオブジェクト。 (ローカルメソッドスタック内)

2. オブジェクトの二次リサイクル

オブジェクトにマークが付いていると言いましたが、マークされていれば必ずリサイクルされるということではないでしょうか? Object クラスには Finalize() メソッドがあることを覚えているかどうかはわかりませんが、すべてのクラスは Object クラスを継承するため、このメソッドはデフォルトで実装されています。

finalize の動作原理は次のようになります。ガベージ コレクターがオブジェクトによって占有されているストレージ領域を解放する準備ができると、最初に Finalize() が呼び出され、次のガベージ コレクション プロセス中にのみ、オブジェクトのメモリが実際に解放されます。したがって、finalize() を使用すると、ガベージ コレクション中にいくつかの重要なクリーニング作業を実行できます。コレクション System.gc() の実行時などに自動的に呼び出されます。

2. Finalize メソッドは、プログラムの終了時にオブジェクトごとに 1 回呼び出されます。

3. Finalize メソッドを明示的に呼び出す


このメソッドの目的は、オブジェクトがリサイクルされる前に、オブジェクトの Finalize() メソッドが呼び出されるということです。

ここでのリサイクルとは、マークされた後のことを指します。問題は、オブジェクトが前の章で述べた「関係ネットワーク」(参照チェーン) に存在しない状況があるのですが、開発者が Finalize() を書き換えた後です。 、オブジェクトは「関係ネットワーク」に再度追加されます。これは、オブジェクトがまだ私たちにとって有用であり、リサイクルすべきではないことを意味しますが、どうすればよいでしょうか?


仮想マシンのアプローチは、2 回マークすることです。つまり、最初に、 「関係ネットワーク」に属していません。 2 回目では、オブジェクトが Finalize() メソッドを実装しているかどうかを最初に判断する必要があります。実装されていない場合は、そのオブジェクトがリサイクル可能であると直接判断され、実装されています。最初にキューに入れられ、仮想マシンによって作成された低レベルが優先スレッドによって実行され、次に 2 番目の小規模なマーキングが実行されます。今回は、マークされたオブジェクトが実際にリサイクルされます。


概要: 簡単に言うと、オブジェクトは初めてマークされ、次の GC の前にオブジェクトの Finalize() メソッドが実行されます。 Finalize()メソッドを実行する際、オブジェクトがfinalize()メソッドを実装しているかどうかを判定し、実装されていない場合は直接クリアし、オブジェクトはfinalizeメソッドを実行するキューに入れられます。 2 回目のマーク
Java ルート検索アルゴリズムで判断 オブジェクトのアクセス可能性は、必ずしも到達不能なオブジェクトをクリーンアップする必要があることを意味するわけではありません。現時点では試用期間があり、オブジェクトが死んだと真に判断するには、少なくとも 2 つのマーキング プロセスを経る必要があります。ルート検索の実行後に GC ルートに関連付けられた参照チェーンが存在しないことが判明した場合は、オブジェクトはそのプロセスを実行します。フィルタリングの条件は、オブジェクトが Finalize() メソッドをカバーしていない場合、または Finalize() メソッドを実行する必要があるかどうかです。仮想マシンによって呼び出された場合、仮想マシンは両方の状況を「実行する必要はありません」として扱います。
つまり、オブジェクトが Finalize() メソッドをオーバーライドすると、そのオブジェクトは Finalize() メソッドを実行する必要があると判断され、そのオブジェクトは F-Queue キューに置かれ、その後、仮想マシンによって自動的に作成された優先度の低いファイナライザー スレッドが実行されます。ここでのいわゆる実行とは、仮想マシンがこのメソッドを開始しますが、実行が完了するまで待つことを約束するものではないことを意味します。この理由: オブジェクトの Finalize() メソッドでの実行が遅い場合、または無限ループが発生した場合 (極端な場合)、F-Queue キュー内の他のオブジェクトが永続的に待機状態になったり、さらにはメモリ全体をリサイクルするシステムがクラッシュします。 Finalize() メソッドは、オブジェクトが死の運命から逃れる最後のチャンスです。その後、オブジェクトが Finalize() で自身を正常に保存したい場合、GC はそのオブジェクトを F キューにマークします。 ---- 参照チェーン上の何かと再関連付けする限り、オブジェクトがこの時点でエスケープされない場合、2 回目にマークされたときに「すぐにリサイクルされる」コレクションから削除されます。 、リサイクルされます。コード例: 「Java 仮想マシンの詳細」の対応する章を参照してください

概要

以上がJava でのリサイクルされたオブジェクトのマーキングとオブジェクトの二次マーキング プロセスの詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。