7

以下のコードが与えられます。

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オブジェクトの作成後にBオブジェクトをガベージコレクションできますか?

4

4 に答える 4

7

このフィールドにはリフレクションを介して(を使用して)アクセスできるため、いいえと思いますsetAccessible(true)

理論的には、コンパイラーはこのフィールドにアクセスされないことを証明でき、Bガベージコレクションの対象になります(JLS 12.6.1ファイナライズの実装から)。

到達可能なオブジェクトとは、ライブスレッドからの潜在的な継続的な計算でアクセスできるオブジェクトです。プログラムの変換を最適化することで、到達可能なオブジェクトの数を、単純に到達可能と見なされるオブジェクトの数よりも少なくするように設計できます。たとえば、コンパイラまたはコードジェネレータは、nullに使用されなくなる変数またはパラメータを設定して、そのようなオブジェクトのストレージをより早く再利用できるようにすることを選択できます。

しかし、実際にはコンパイラとJVMはそれほど賢いとは思いません

于 2012-09-28T08:17:22.587 に答える
1

標準のコンパイラはそれほど賢くはありません。

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());
    }
}

このコードは、非常に少数のループの後にメモリ不足の例外をスローするため、元の質問に対する答えは間違いなくノーです。

于 2012-09-28T08:27:00.773 に答える
1

@Kubaつまり、クラスのインスタンスBのフィールドにあるクラスのインスタンスをガベージコレクションできますか?いいえ。が参照されているように、そうではありません。baAanullba

于 2012-09-28T08:19:45.457 に答える
1

いいえ、メインスレッドにはbスルーへのパスがあるためaです。

于 2012-09-28T08:20:15.987 に答える