java фантомные phantomreference - Циркулярные ссылки в Java




5 Answers

Только очень наивная реализация будет иметь проблемы с циркулярными ссылками. В Википедии есть хорошая article о различных алгоритмах GC. Если вы действительно хотите узнать больше, попробуйте (Amazon) Garbage Collection: Алгоритмы автоматического управления динамической памятью . У Java был хороший сборщик мусора с 1.2 и исключительно хороший в 1.5 и Java 6.

Трудная часть для улучшения GC - это сокращение пауз и накладных расходов, а не основных вещей, таких как круговая ссылка.

weakreference referencequeue

Учитывая агрегацию экземпляров класса, которые относятся друг к другу в сложной, круглой форме: возможно ли, что сборщик мусора не сможет освободить эти объекты?

Я смутно помню, что это было проблемой в JVM в прошлом, но я думал, что это было решено много лет назад. Тем не менее, некоторые исследования в jhat показали, что циркулярная ссылка является причиной утечки памяти, с которой я столкнулся сейчас.

Примечание. У меня всегда создалось впечатление, что JVM способна разрешать циркулярные ссылки и освобождать из памяти такие «острова мусора». Тем не менее, я задаю этот вопрос только для того, чтобы узнать, не нашли ли какие-либо исключения.




Райан, судя по вашему комментарию к Circular References на Java , вы попали в ловушку ссылок объектов из класса, который, вероятно, был загружен загрузчиком bootstrap / system classloader. Каждому классу ссылается загрузчик классов, который загружает класс, и поэтому может быть собран в мусор, только если загрузчик классов больше не доступен. Ловушка заключается в том, что загрузчик bootstrap / system никогда не собирает мусор, поэтому объекты, доступные из классов, загружаемых системным загрузчиком классов, также не могут быть собраны в мусор.

Обоснование такого поведения объясняется в JLS. Например, третье издание 12.7 http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7 .




Нет, по крайней мере, используя официальную JVM Sun, сборщик мусора сможет обнаружить эти циклы и освободить память, как только больше не будет ссылок снаружи.




Просто чтобы усилить то, что уже было сказано:

Приложение, с которым я работаю в течение шести лет, недавно изменилось с Java 1.4 на Java 1.6, и мы обнаружили, что нам пришлось добавлять статические ссылки на вещи, которые мы даже не понимали, раньше собирали мусор. Нам не нужна статическая ссылка раньше, потому что сборщик мусора использовал, чтобы сосать, и теперь это намного лучше.




Циклическая ссылка происходит, когда один объект ссылается на другой, а другой ссылается на первый объект. Например:

class A {
private B b;

public void setB(B b) {
    this.b = b;
}
}

class B {
private A a;

public void setA(A a) {
    this.a = a;
}
}

public class Main {
public static void main(String[] args) {
    A one = new A();
    B two = new B();

    // Make the objects refer to each other (creates a circular reference)
    one.setB(two);
    two.setA(one);

    // Throw away the references from the main method; the two objects are
    // still referring to each other
    one = null;
    two = null;
}
}

Сборщик мусора Java достаточно умен, чтобы очищать объекты, если есть круглые ссылки, но нет живых потоков, которые имеют какие-либо ссылки на объекты больше. Таким образом, такая циклическая ссылка не создает утечки памяти.




Related