2010-09-08 2 views
4
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); 
    System.out.println("c3 value : "+c3); 
    c1 = null; 
    System.out.println("c1 value : "+c1); 
    System.out.println("c2 value : "+c2); 
    // do Stuff 
    } 
} 

Это пример экзамена SCJP6 mock. В этом вопросе говорится: когда достигается // doStuff, сколько объектов имеет право на GC? И ответ (2 объекта), потому что: только один объект CardBoard (c1) имеет право, но имеет связанный с ним объект-обертку Short , который также имеет право на участие.Какие объекты имеют право на GC?

Когда я выполняю код, похоже, что c3 также указывает на null ... поэтому я бы сказал, что 3 объекта имеют право на GC.

Может кто-нибудь, пожалуйста, проведет меня через логику этого кода.

ответ

10

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

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

Это оставляет нам c1, который был явно аннулирован и, следовательно, имеет право на сбор. Однако c1 также содержит ссылку на историю изменений Short, которая не имеет каких-либо входящих ссылок от любого другого объекта. Это приводит к тому, что два объекта имеют право на очистку - один объект CardBoard и встроенный объект Short.

+1

или, если сказать, очень просто: в этом коде есть только два случая ключевого слова 'new', и они выполняются только один раз (они ' re в основном методе, а не в итерации) .Так по определению этот код создает только два объекта.Как он мог когда-либо собирать больше? –

+0

@Joeri, без сомнения, вы правы. Но нелегко вывести число объектов, подходящих для сбора, в зависимости от количества созданных объектов. Да, это хороший показатель, но более важно учитывать ссылки, и очень просто ошибиться там, просто прочитав код. –

+0

Конечно, Я полностью согласен. Именно в этом случае код настолько предельно прост, вам даже не нужно смотреть дальше. Тем не менее, хорошее упражнение. –

1

c3 никогда не указывает на какой-либо объект, он всегда является нулевой переменной. Следовательно, объект c3 не подходит для GC

0

В вашем коде только c1 и история (Short), содержащиеся в c1, имеют право на GC. т. Е. 2 ​​объекта.

c3 никогда не ссылается ни на какой объект, поскольку метод go() возвращает null.

c2 не подходит для GC. Как и в аргументе Java, аргументы передаются по значению. и когда метод go называется c2, он продолжает указывать на объект, хотя в методе go передается переменная, которой присваивается значение null.

+0

Неверный. Ссылка c2 никогда не назначается 'null'. Метод 'go' - это трюк, чтобы понять, понимает ли читатель, что Java НЕ использует pass-by-reference. –

+0

в '// doStuff',' c2 'все еще ссылается на 'CardBoard', поэтому ** не ** подходит для gc. Два объекта: 'c1' и' Short' внутри него, как говорит Vineet. – mikej

+0

Спасибо, что я уже обновлял свой ответ с информацией, которую я процитировал неправильно :( – YoK

2

CardBoard c1 = new CardBoard();

Создает экземпляр CardBoard и его пример Short. (2 объекта) Присваивает CardBoard ссылку на c1.

CardBoard c2 = new CardBoard();

Создает экземпляр CardBoard и его пример Short. (Еще 2 объекта) Присваивает CardBoard ссылку на c2.

CardBoard c3 = c1.идти (с2);

Присвоение null по c3. (Метод go - это трюк, чтобы понять, понимаете ли вы семантику передачи аргументов Java. Если вы считаете, что Java использует pass-by-reference, вы можете ошибочно заключить, что c2 этим вызовом имеет null. Фактически, c2 не изменился.)

c1 = null;

Назначение: null - c1. Это делает первый экземпляр CardBoard и его экземпляр Short недоступным и кандидатами на сбор мусора.

Второй экземпляр CardBoard и его пример Short по-прежнему доступны.

Смежные вопросы