Оба объекта становятся недостижимыми от GC roots и могут быть собраны, несмотря на взаимные ссылки. Java GC не опирается только на подсчёт ссылок.
Взаимные ссылки между объектами и поведение сборщика мусора в Java
Оба объекта становятся недостижимыми от GC roots и могут быть собраны, несмотря на взаимные ссылки. Java GC не опирается только на подсчёт ссылок.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Рассмотрите, как будет вести себя система при наличии взаимных ссылок между объектами. Что произойдёт с объектами, если после их взаимного связывания ссылки из локальных переменных будут обнулены и будет запрошен запуск сборки мусора?
class A {
B b;
}
class B {
A a;
}
public class main {
public static void main(String [] args){
A objA = new A();
B objB = new B();
objA.b = objB;
objB.a = objA;
objA = null;
objB = null;
System.gc();
}
}
Ответ
Оба объекта становятся недостижимыми от GC roots и могут быть собраны, несмотря на взаимные ссылки. Java GC не опирается только на подсчёт ссылок.
Цикл A ↔ B не удерживает объекты, если к нему больше нет пути от живых потоков, статических корней и других GC roots. Обнуление objA и objB устраняет показанные внешние ссылки. System.gc() лишь запрашивает сборку и не гарантирует немедленного освобождения памяти или конкретного момента исполнения. Иная ситуация была бы, если один из объектов сохранился в статической коллекции: тогда весь цикл оставался бы достижимым.