Сборка мусора в Java и нулевая ссылка

Во время учебы в OCJP я столкнулся со следующим вопросом:

class CardBoard {
           Short story = 200;
           CardBoard go(CardBoard cb) {
                cb = null;
                return cb;
           }
           public static void main(String[] args) {
             CardBoard c1 = new CardBoard();
             CardBoard c2 = new CardBoard();
             CardBoard c3 = c1.go(c2);
             c1 = null;
            // do Stuff 
}}

Когда достигается //doStuff, сколько объектов подходит для GC?
Правильный ответ — 2, что означает c1 и его story объект.

Когда достигается строка //doStuff, c3 также имеет значение null. Почему он тоже не подходит для GC?


person Maggie    schedule 28.10.2012    source источник
comment
Потому что ему никогда не присваивалось значение :). Он был нулевым с самого начала.   -  person Amit Deshpande    schedule 28.10.2012


Ответы (6)


c3 — это локальный дескриптор с нулевой ссылкой, он не указывает (и никогда не указывал) на выделенный объект. Поэтому нет ничего для GC.

person onon15    schedule 28.10.2012

c3 не является объектом. Это переменная, ссылающаяся на null. Переменная не может быть допущена к сборке мусора. Только объекты могут иметь право на GC.

Объектами, имеющими право на GC, являются Cardboard, на который изначально ссылается c1, и экземпляр Short, на который изначально ссылается CardBoard, на который первоначально ссылается c1.

person JB Nizet    schedule 28.10.2012

Сборщик мусора сканирует объекты в памяти и, когда находит, проверяет наличие дескрипторов, указывающих на него (а не наоборот). Когда сборщик мусора вызывается, объекты (внутри памяти), у которых нет дескриптора, указывающего на них, удаляются из памяти. В этом случае кода у вас есть только 2 объекта, созданные в памяти, но три дескриптора. Сборщик мусора удалит не более 2 объектов (поскольку существует только два объекта). C3 указывал только на нулевую позицию. C1,C2,C3 не удаляются. Объекты, на которые они раньше указывали, удаляются (если на них не указывает другой дескриптор). Таким образом, на данный момент, поскольку C3 никогда не указывал на объект в памяти, установка его в значение null не имеет значения для сборщика мусора.

Надеюсь, я был полезен

person John Demetriou    schedule 28.10.2012

Ваш метод CardBoard#go() ничего не делает. Он получает ссылку на какой-то объект, тут же забывает ее, заменяя на null, и возвращает это значение null.

Итак, линия

CardBoard c3 = c1.go(c2);

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

person Dims    schedule 28.10.2012

c3 сама по себе является просто ссылочной переменной, которая не находится в пространстве кучи (т.е. не в области видимости). сбор мусора)

Строка CardBoard c3 = c1.go(c2); только устанавливает ссылку c3 на null. Таким образом, c3 не влияет на сборку мусора, поскольку не делает подходящим объект.

person Nash    schedule 22.12.2017

c3 не имеет ссылок на объект, это просто для путаницы.

Мы создали два объекта c1 и c2, чего нам не хватает, так это объектов-оболочек типа Short, поэтому всего мы создали четыре объекта.

Когда мы делаем c1 = null, это означает, что короткий объект, к которому мы обращаемся, используя c1, доступен для GC, а не короткий объект, к которому мы можем получить доступ, используя c2.

Это можно проверить с помощью следующего кода:

открытый класс CardBoard {

Short story = 200;

CardBoard go(CardBoard cb) {
    cb = null;
    return cb;
}

public static void main(String[] args) {
    Runtime run = Runtime.getRuntime();

    CardBoard c1 = new CardBoard();
    CardBoard c2 = new CardBoard();
    CardBoard c3 = c1.go(c2);

    // System.out.println(run.freeMemory());

    run.gc();
    // System.out.println(run.freeMemory());

    c1.story = 100;

    System.out.println(c1.story);
    c1 = null;
    run.gc();

    System.out.println(c2.story);

}

}

вывод: 100 200

это означает, что c1 и Short story, к которым мы можем получить доступ из c1, доступны для сборки мусора, а не Short story of c2.

person Vinayak Bansal    schedule 12.01.2018