2012-09-28 6 views
5

以下のコードを与えます。プライベートフィールドのガベージコレクション

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

class Main { 
    public static void main(String[] args) { 
     A a = new A(); // two objects are created (a and b) 
     // <-- is B object, referenced only by private a.b eligible for garbage collection? 
     keepAlive(a); 
    } 
} 

Aオブジェクトの作成後にCan Bオブジェクトをガベージコレクションすることはできますか?

答えて

6

私はまだこのフィールドは反射(setAccessible(true)を使用)でアクセスできるため、いいえとは思いません。理論的に

、コンパイラは、このフィールドにアクセスすることはないだろうことを証明することができ、それは(JLS 12.6.1 Implementing Finalizationから)ガベージコレクションのBが適格になるだろう:

到達可能なオブジェクトは、あらゆる潜在的にアクセスすることができる任意のオブジェクトでありますライブスレッドから計算を継続します。プログラムの変換を最適化することで、到達可能なオブジェクトの数を、到達不能であると考えられるオブジェクトの数よりも少なくすることができます。例えば、コンパイラまたはコードジェネレータは、もはやヌルに使用されない変数またはパラメータを設定して、そのようなオブジェクトの記憶域を潜在的に再要求可能にすることを選択することができる。

しかし、私は練習のコンパイラとJVMでスマート

1

@Kubaはあなたが意味するかということであるとは思わない:フィールドクラスAのインスタンスabでクラスBのインスタンスがゴミを収集することができます?いいえ、anullではありませんが、baと表示されています。

1

いいえ。メインスレッドのパスはbからaです。

0

標準コンパイラはそれほどスマートではありません。

class A 
{ 
    private Object[] array; 

    public A() 
    { 
     array = new Object[10000000]; 
    } 
} 

public static void main(String[] args) 
{ 
    LinkedList<A> list = new LinkedList<A>(); 
    while (true) 
    { 
     list.add(new A()); 
    } 
} 

このコードは、非常に少数のループの後にメモリ例外をスローするので、元の質問に対する答えは間違いなくありません。

関連する問題