オブジェクトの生存とオブジェクトの参照の判断

1. オブジェクトの生存の判断

ほとんどすべてのオブジェクト インスタンスはヒープに格納されます。ガベージ コレクターがオブジェクトをリサイクルする前に行うべきことは、これらのオブジェクトのうちどのオブジェクトがまだ「生存」しており、どのオブジェクトが「死滅」しているかを判断することです (死滅は再利用が不可能であることを意味します) ) オブジェクトを使用する任意の方法)

1.1、参照カウントアルゴリズム

オブジェクトに参照カウンタを追加します。オブジェクトへの参照があるたびに、カウンタは 1 ずつ増加します。

次のコードに示すように:

String p = new String("abc");

ここに画像の説明を挿入

上記のコードのメソッドが終了するか、その参照を手動で削除したとき

p = null;

ここに画像の説明を挿入

上記は参照カウントのアルゴリズムであり、高速、便利、実装が簡単という利点がありますが、オブジェクトが相互に参照する場合、オブジェクトをリサイクルすべきかどうかの判断が難しいという欠点もあります。
ここに画像の説明を挿入
上の模式図では、オブジェクト間で相互参照が発生し、リングデータが生成されます。リングデータが使い道がなくても、参照が0ではないため再利用されることはなく、「メモリリーク」が発生します。問題。


1.2. アクセシビリティ分析アルゴリズム

「GC ルート」と呼ばれる一連のオブジェクトを起点として、そのノードから下方向に探索を開始します。その探索でたどる経路を参照チェーン (Reference Chain) と呼びます。オブジェクトが参照なしで GC ルートに接続されている場合chain は、オブジェクトが利用できないことを証明します。

GC ルートとして使用されるオブジェクトには主に次のようなものがあります。

  • 仮想マシン スタック (スタック フレーム内のローカル変数テーブル) で参照されるオブジェクト。
  • メソッド領域のクラス静的プロパティによって参照されるオブジェクト。
  • メソッド領域の定数によって参照されるオブジェクト。
  • ローカル メソッド スタック内の JNI (つまり、一般的なネイティブ メソッド) によって参照されるオブジェクト。

ここに画像の説明を挿入

1.3、ファイナライズメソッド

到達不可能なオブジェクトが到達可能性分析アルゴリズムによって判断された場合でも、そのオブジェクトは「死ななければならない」わけではなく、依然として「保護観察」段階にあります。オブジェクトを実際に死んでいると宣言するには、2 つのマーキング プロセスを経る必要があります。見つからず、 GCRoots の場合、初めてマークされます。次に、スクリーニングを実行します (オブジェクトがファイナライズ メソッドをオーバーライドする場合)。ファイナライズで保存できます。

ただし、このメソッドの優先度が低く、呼び出し順序が保証されず、不確実性が大きいことに加え、このメソッドはシステムによって自動的に 1 回しか呼び出されないため、一般にこのメソッドの使用は推奨されません。 、2回目は呼び出されません。一般的にはtry-finallyで処理することを推奨します。


1.4. メソッドエリアでのリサイクル

Java 仮想マシンの仕様では、メソッド領域でのガベージ コレクションの効率が低いため、ヒープ メソッド領域でガベージ コレクションを実装する必要はありませんが、一般メソッド領域でのガベージ コレクションの主な内容は、定数と不要なクラスの破棄です。

たとえば、文字列「abc」が定数プールに入った場合、現在のシステムに「abc」という名前の String オブジェクトがない場合、つまり定数プールにその文字列を参照する String オブジェクトがない場合、これは「abc」になります。 「一定。リサイクルできます。」

前述したように、定数が再利用可能かどうかの判断は比較的簡単ですが、不要なクラスのガベージコレクションの条件はより厳しく、以下の点を満たす必要があります。

  • このクラスのすべてのインスタンスはリサイクルされています。つまり、ヒープ内にこのクラスのインスタンスはありません。
  • このクラスをロードした ClassLoader はリサイクルされました。
  • このクラスに対応する java.lang.Class オブジェクトはどこからも参照されず、リフレクションを通じてこのクラスのメソッドにアクセスすることはできません。
  • -Xnoclassgcクラスをリサイクルするかどうかを制御するために使用される、仮想マシンの関連パラメータの設定を確認する必要があります。

次に、オブジェクト参照

参照カウントアルゴリズムでオブジェクトへの参照数を判断する場合も、到達可能性解析アルゴリズムでオブジェクトの参照チェーンに到達可能かどうかを判断する場合も、オブジェクトが生き残るかどうかを判断する場合も、「参照」に関係します。JDK1.2 以降、Java では参照の概念が次のように拡張されました。

2.1、強参照

これは、プログラム コード内でこのように遍在する参照を指しますObject ojb = new Object()。強参照がまだ存在する限り、ガベージ コレクターは参照されたオブジェクトをリサイクルしません。

2.2、ソフトリファレンス

便利だが必須ではないオブジェクトを説明するために使用されます。ソフト参照に関連付けられたオブジェクトの場合、システムがメモリ オーバーフロー例外を検出する前に、これらのオブジェクトは 2 回目のリサイクルのリサイクル範囲に含まれます。登録とリサイクルに十分なメモリがない場合は、メモリ不足例外がスローされます。JDK1.2以降では、ソフト参照を実装するためのSoftReferenceクラスが提供されています。

たとえば、ユーザーが提供した画像を処理するためにプログラムが使用されます。すべての写真がメモリに読み込まれると、写真はすぐに開くことができますが、メモリ スペースが膨大になり、あまり使用されない一部の写真はメモリ スペースを浪費するため、メモリから手動で削除する必要があります。画像を開くたびにディスクファイルからメモリに読み込んで表示すると、メモリ使用量は少ないですが、よく使う画像によっては開くたびにディスクにアクセスする必要があり、コストが膨大になります。現時点では、ソフト参照を使用してキャッシュを構築できます。

2.3、弱引用

必須ではないオブジェクトを記述するために使用されますが、その強度はソフト参照よりも弱く、弱い参照に関連付けられたオブジェクトは次のガベージ コレクションが発生するまでしか存続できません。ガベージ コレクターが動作すると、現在のメモリが十分であるかどうかに関係なく、弱い参照にのみ関連付けられているオブジェクトが再利用されます。JDK1.2以降では、弱参照を実装するためにWeakReferenceクラスが提供されています。

注:ソフト参照 SoftReference と弱参照 WeakReference は、メモリ リソースが不足している場合や、あまり重要ではないデータ キャッシュを作成する場合に使用できます。システム メモリが不足している場合、キャッシュ内のコンテンツが解放されることがあります。

実用的なアプリケーション: ThreadLocal、WeakHashMap

2.4. ファントム参照

ゴースト参照またはファントム参照とも呼ばれ、最も弱い種類の参照関係です。オブジェクトに仮想参照があるかどうかは、その存続期間にまったく影響せず、仮想参照を通じてオブジェクト インスタンスを取得することはできません。オブジェクトへのファントム参照を設定する唯一の目的は、オブジェクトがコレクターによって再利用されたときにシステム通知を受け取ることです。JDK1.2以降では、仮想参照を実装するためにPhantomReferenceクラスが提供されています。

おすすめ

転載: blog.csdn.net/rockvine/article/details/124608548