10

Objective C では、2 つの異なる参照が相互に指す可能性があります。

しかし、これはJavaで可能ですか?つまり、2 つのオブジェクト参照が相互に参照できるのでしょうか? 可能であれば、いつガベージコレクションされますか?

また、ネストされたクラスの場合、2 つのオブジェクト (内部クラスと外部クラス) が相互にリンクされます。これらのオブジェクトはどのようにガベージ コレクションされますか?

4

3 に答える 3

34

循環参照について話していると思います。Java の GC は、GC ルートから始まるチェーンを介してオブジェクトに到達できない場合、オブジェクトを「ガベージ」と見なします。オブジェクトが相互にポイントしてサイクルを形成する場合でも、ルートから切断された場合でも GC の対象となります。

Java には 4 種類の GC ルートがあります。

  1. ローカル変数は、スレッドのスタックによって維持されます。これは実際のオブジェクトの仮想参照ではないため、表示されません。すべての意図と目的において、ローカル変数は GC ルートです。

  2. アクティブな Java スレッドは常にライブ オブジェクトと見なされるため、GC ルートになります。これは、スレッド ローカル変数の場合に特に重要です。

  3. 静的変数は、そのクラスによって参照されます。この事実により、それらは事実上の GC ルートになります。クラス自体をガベージ コレクションすることができます。これにより、参照されているすべての静的変数が削除されます。これは、アプリケーション サーバー、OSGi コンテナー、またはクラス ローダーを一般的に使用する場合に特に重要です。

  4. JNI 参照は、ネイティブ コードが JNI 呼び出しの一部として作成した Java オブジェクトです。このように作成されたオブジェクトは、ネイティブ コードによって参照されているかどうかを JVM が認識できないため、特別に扱われます。このようなオブジェクトは、GC ルートの非常に特殊な形式を表します。

詳細については、こちらを参照することもできます。

ここに画像の説明を入力

于 2013-07-11T07:08:57.127 に答える
7

はい、できます。このような:

class Pointy {
    public Pointy other;
}

Pointy one = new Pointy();
Pointy two = new Pointy();
one.other = two;
two.other = one;

これらは、両方のオブジェクトが互いに他のオブジェクトによって指されていない場合、または現在実行中のコードから「到達できない」他のオブジェクトによって指されていない場合にガベージ コレクションされます。Java ガベージ コレクタは「トレース」ガベージ コレクタです。これは、この種の問題を発見できることを意味します。

逆に、参照カウントシステム ("最新の" ガベージ コレクションのない Objective C など - デフォルトが何かはわかりません) は、通常、この種の問題を検出できないため、オブジェクトがリークされる可能性があります。

于 2013-07-11T07:12:50.783 に答える
4

もちろん、オブジェクトを相互に参照させることもできます。this両方のオブジェクトのポインターを相互に渡すだけで済みますが、これは完全に有効です。

ただし、これはオブジェクトが GC ルートから引き続きアクセスできるという意味ではありません。(グラフ) ツリーと考えてください。幹から完全な枝を切り離すと、関連するオブジェクトの数や相互参照を維持しているオブジェクトの数に関係なく、枝全体が失われます。

于 2013-07-11T07:12:05.350 に答える