3

(このサイトhttp://scjptest.com/で)質問がありました:このコードサンプルの行//にあるコードで、ガベージコレクションの対象となるオブジェクトの数はいくつですか?

class A {
    private B b;
    public A() {
        this.b = new B(this);
    }
}

class B {
    private A a;
    public B(A a) {
        this.a = a;
    }
}

public class Test { 
    public static void main(String args[]) {
        A aa = new A();
        aa = null;
        // some code goes here
    }
}

正解は、「aとbによって参照されるオブジェクトはガベージコレクションの対象です。」です。しかし、なぜ?それらは相互へのループ参照を含み、相互にアクセス可能です。

ありがとうございました!

4

4 に答える 4

5

それらには相互へのループ参照が含まれており、相互にアクセスできます。

はい。ただし、他の場所からはアクセスできなくなったため、プログラムで表示したり使用したりすることはできなくなりました。

初期のGCには、このような自己参照オブジェクトグループの収集に問題がありましたが、最新の世代別コレクターでは、問題は解決されています。

簡単に言うと、GCは、既知の静的オブジェクトとスタックオブジェクトからの参照のウェブをウォークスルーできます。

  • 見つかったすべてのオブジェクトを新しいメモリプールにコピーし、「デッド」オブジェクトを自動的に残します(これは「若い世代」の戦略です)。
  • 見つかったすべてのオブジェクトにマークを付けて、参照のWeb全体をトラバースすると、マークされていないすべてのオブジェクトを削除できるようにします(これは「古い/古い世代」の戦略です)。
于 2011-04-27T09:14:38.003 に答える
2

これは、Javaには世代別のガベージコレクターがあるため、メインアプリケーションからではなく、オブジェクト間の参照を持つオブジェクトのグループを収集できるためです。

ここに、より詳細な説明があります

私が覚えている限り(そして私は間違っているかもしれませんが)、これは古いバージョンのjava(java 1.2など)には当てはまりませんでした。GCがそれらを収集するために循環依存関係を手動でクリアする必要がありました。

于 2011-04-27T09:12:58.590 に答える
2

その「島」(またはグループ)のどのオブジェクトにもどのスレッドからもアクセスできない場合、GCはいわゆる「オブジェクトの島」を削除できます。

この例では、別のオブジェクトBにリンクするオブジェクトAを作成します。ただし、オブジェクトBは、Aを期待する人が「参照可能」ではありません。2つのオブジェクトを島として表示できます。Aがなくなると、GCは、Bが他のスレッドから参照できないことを理解できるほど賢くなり、2つのオブジェクトが削除されます。

于 2011-04-27T09:59:14.857 に答える
1

明確に理解するためにシナリオを描きましょう。

A a = new A() 

a------------これはオブジェクトを指します------------>A()「最初のオブジェクト」

A()のコンストラクターで、B()「2番目のオブジェクト」のインスタンスをインスタンス化します。

クラスBインスタンス内では、上記のA()を指しているだけなので、新しいオブジェクトは作成されません。「a」変数にnull値を割り当てた時点では、A()オブジェクトを指す参照はありません。これで、GCに適格な2つのオブジェクトができました。クラスが相互に参照していることを心配する必要はありません。メインメソッド内の宣言に注目してください。

于 2011-08-01T08:36:54.947 に答える