Сколько объектов будет иметь право на сбор мусора после выполнения "m1=null; m2=null;"?
Я запутался, чтобы понять после выполнения m1 = null;
m2 = null;
. Сколько объектов будет иметь право на вывоз мусора?
public class MyTest {
MyTest m;
void show() {
System.out.println("Hello this is show method.");
}
public static void main(String args[]) {
MyTest m1 = new MyTest();
MyTest m2 = new MyTest();
MyTest m3 = new MyTest();
m1.m = m2;
m2.m = m3;
m3.m = m1;
m1 = null;
m2 = null;
// Question here: How many objects will be eligible for garbage collection?
}
}
4 ответа:
ноль.
схема ссылок на объекты выглядит так:
вы можете видеть, что ссылка является круговой. Ссылка от
main
доm3
держитm3
объект жив. В свою очередь,m3
живойm1
, которая держитm2
С GC.обратите внимание, что если вы установите
m3
tonull
, все три объекта будут иметь право на GC сразу, несмотря на циклические ссылки, существующие для каждого из них. GC достаточно умен, чтобы понять, что все ссылки поступают из объектов, имеющих право на GC, и собирают все три.
потенциально все 3 из них. Никакие переменные не ссылаются после
//
маркер, так что оптимизатор в пределах своих прав, чтобы сбросить их с кадра в этот момент.
вуаля! GC здесь ничего не соберут! Давайте посмотрим, что на самом деле здесь происходит. Когда вы создали три объекта
m1
,m2
иm3
наMyTest
, объект был создан, как показано ниже (скажем, идентификатор ссылки на объект начинается с 410):m1 MyTest (id=410) m null m2 MyTest (id=412) m null m3 MyTest (id=414) m null
при инициализации
m1.m = m2; m2.m = m3; m3.m = m1;
объекты теперь выглядит так:
m1 MyTest (id=410) m MyTest (id=412) m2 MyTest (id=412) m MyTest (id=414) m3 MyTest (id=414) m MyTest (id=410) m MyTest (id=412) m MyTest (id=414) m MyTest (id=410) . . . (This is circular)
но после инициализации
m1
иm2
доnull
, объекты например:m1 null m2 null m3 MyTest (id=414) m MyTest (id=410) m MyTest (id=412) m MyTest (id=414) m MyTest (id=410) . . .
Послушай,
m1
иm2
arenull
сейчас, но их ссылки все еще живы вm3
!