SCJP Mock Вопрос: Сколько объектов подходит для сборки мусора? - PullRequest
3 голосов
/ 27 апреля 2011

Мне задали вопрос (на этом сайте 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
    }
}

Theправильный ответ: «Объекты, на которые ссылаются a и b, имеют право на сборку мусора». Но почему? они содержат ссылки на циклы друг на друга, они доступны друг другу.

Спасибо!

Ответы [ 4 ]

5 голосов
/ 27 апреля 2011

они содержат циклические ссылки друг на друга, они доступны друг другу.

Да, но они больше недоступны из других мест, поэтому их больше нельзя увидеть и использовать в программе.

Ранние сборщики мусора сталкивались с проблемами при сборе таких данных.ссылка на группы объектов, но с современными сборщиками поколений это решаемая проблема.

Короче говоря, GC может просматривать сеть ссылок из известных статических и стековых объектов, а также

  • скопировать все найденные объекты в новый пул памяти, автоматически оставляя после себя «мертвые» объекты (это стратегия «молодого поколения»), или
  • пометить все найденные объекты, чтобы однажды вся сеть ссылокпройден, он может удалить все немаркированные объекты (это стратегия «старое / постоянное поколение»).
2 голосов
/ 27 апреля 2011

GC может удалить так называемый «остров объектов», если ни один из объектов этого «острова» (или группы) не может быть доступен из любого потока!

В вашем примереВы создаете объект A, который имеет ссылку на другой объект B. Но объект B не является «справочно-ориентированным», если кто-либо не ожидает, что A. Вы можете рассматривать два объекта как остров.Когда A уйдет, GC будет достаточно умен, чтобы понять, что B не может ссылаться ни на какой другой поток, и поэтому у вас будет 2 объекта, которые будут удалены.

2 голосов
/ 27 апреля 2011

Это потому, что у java есть поколенный сборщик мусора , поэтому он может собирать группы объектов, между которыми есть ссылки, но не из приложения main .

Более подробное объяснение здесь .

Насколько я помню (и я могу ошибаться), это было не так со старыми версиями java (такими как java 1.2), в которых циклические зависимости нужно было очищать вручную, чтобы GC собирал их.

1 голос
/ 01 августа 2011

Давайте нарисуем сценарий, чтобы понять ясно.

A a = new A() 

a ------------ это указывает на объект ------------> A () "1-й объект"

в конструкторе A () вы создаете экземпляр экземпляра B () "2nd object"

внутри экземпляра класса B просто указывает на A () выше, поэтому новый объект не создается. В тот момент, когда вы присвоили нулевое значение переменной «a», никакая ссылка не будет указывать на объект A (). Теперь у вас есть 2 объекта, подходящих для GC. Не беспокойтесь о классах, ссылающихся друг на друга, просто сосредоточьтесь на объявлении внутри вашего метода main.

...