Вопрос по сборщику мусора

Рейтинг: 0Ответов: 1Опубликовано: 29.01.2015

Есть объявление глобальной переменной Client t.

В одном из методов создал (t = new Client("name1"));.

Забросил этот объект в ArrayList.

Затем снова создал новый объект на ту же ссылку (t = new Client(name2));.

Забросил и этот объект в ArrayList.

Удалит ли "сборщик мусора" предыдущий объект?

Смогу ли я обращаться к предыдущему объекту?

Ответы

▲ 3Принят

Сборщик мусора не будет удалять объект, пока на него есть хоть одна ссылка. Исключением являются случаи обособленных циклических ссылок: если A ссылается на B, B ссылается на A, при этом ни на A, ни на B никто больше не ссылается, то оба объекта будут удалены. Если вы положили объект в список, то внутри списка на него создана ссылка. Пока вы не потеряете ссылку на список, сборщик мусора не будет удалять объекты, хранящиеся в списке.

Client t = new Client("name1");
List<Client> l = new ArrayList<>();
l.add(t);                    // Сейчас на Client("name1") 2 ссылки - t и внутри l
t = new Client("name2");     // А сейчас только одна - внутри l
l = null;                    // Пропала последняя ссылка на l, поэтому GC его удалит
// А после удаления l никто не будет ссылаться на Client("name1"), и его тоже удалят

Важно помнить, что сборщик мусора отрабатывает не сразу, а только при необходимости (например, если заканчивается память). Поэтому объект может провисеть в памяти неопределённое время после исчезновения всех ссылок на него. Также стоит помнить, что нет надёжного способа вручную запустить сборщик мусора. Метод System.gc() является лишь "советом" запустить сборку, и JVM может его проигнорировать, если считает, что в данный момент сборка не нужна.