2015-08-30 3 views
3

Какие объекты доступны для сбора мусора во время вызова System.gc() и почему?Работа сборщика мусора в Java

public class GCTest { 
    static class A { 
     private String myName; 
     public A(String myName) { 
      this.myName = myName; 
     } 
    } 

    public static void main(String[] args) { 
     A a1 = new A("a1"); 
     A a2 = new A("a2"); 
     ArrayList list = new ArrayList(); 
     list.add(a1); 
     A[] mas = new A[2]; 
     mas[0] = a2; 
     a2 = a1; 
     clear(mas); 
     a1 = null; 
     a2 = null; 
     System.gc(); 
     // some code 
     ... 
    } 

    private static void clear(A[] mas) { 
     mas = null; 
    } 
} 

если object == null это будет мусором или нет?

Я думаю a1, a2 и mas доступны для сбора мусора на момент вызова System.gc(), потому что это утверждать нуль. или я ошибаюсь?

+0

Соответствует: http://stackoverflow.com/a/18930323/1103872 –

ответ

8

Во-первых, ваши программные переменные никогда не «доступны для сбора мусора». Только объекты собираются GC, а программные переменные - ссылки на объекты, а не на объекты. (Общая терминология со ссылкой на Java переменных путает эту точку.)

Во-вторых, ни один из объектов не ссылается a1, a2 или mas будут GC'ed. Это несмотря на то, что a1 и a2 установлены на null. Это связано с тем, что ссылки на эти объекты по-прежнему доступны через list или mas.Почему объект, на который ссылается a2, все еще доступен через mas даже после звонка clear()? Поскольку вы не можете изменить значение переменной mas в main(), передав переменную методу clear(). Все, что вы делаете в этом методе, меняет формальный параметр (также называемый mas), который является отдельной переменной из локальной переменной в main(). Java строго передается по значению. Однако, когда дело доходит до объектов, то, что всегда передается, является ссылкой .

В общем, правило состоит в том, что объекты GC'ed, только если объекты недоступны из любой программной переменной, прямо или косвенно.

+0

Я признаю, что это одна из тестовых задач на работе. скорее всего, я его не отправлю, но меня очень интересовало, как это работает. спасибо вам объяснили. Я также хотел бы прочитать о тонкостях и работе Java, если вы порекомендуете интересную статью или книгу – ip696

+0

@ ip696. Я всегда предлагаю начать с [учебников по Java] (https://docs.oracle.com/javase/tutorial/). Они точны и достаточно тщательны. –

2

Никто не будет иметь право на GC:

  1. ArrayList еще достижимы и ссылки a1.
  2. Оба a2 и a1 ссылаются на этот же объект.
  3. Самое главное, так как Java является передача по значению, метод clear будет не фактически очистить массив mas передается от main.

Ниже приводится иллюстрация объектов в памяти, когда GC вызывается:

enter image description here

2

Ничто не доступен для GC в это время:

  • вы все еще есть ссылка (list), ссылающийся на ArrayList, содержащий объект, на который первоначально ссылался a1 (тот, который содержит строку «a1» внутри)
  • вы все еще есть ссылка (mas), ссылающийся на массив, содержащий объект сначала ссылается a2 (тот, с «а2» строки внутри)

Обратите внимание, что ваш метод

private static void clear(A[] mas) { 
    mas = null; 
} 

ничего не делает.

Java передается по значению. Поэтому при вызове этого метода создается копия ссылки на массив и передается методу. Затем метод присваивает значение null копиям исходной ссылки, оставляя исходную ссылку нетронутой.

См. Is Java "pass-by-reference" or "pass-by-value"? для получения дополнительных пояснений.

0

Объект, созданный новым A («a1»), новым A («a2») и mas, не был собран мусором, когда вы вызываете System.gc().

Любой объект, на который прямо или косвенно ссылаются потоки, недоступен для gc. Этот поток запускает этот метод, поэтому локальные переменные будут сохранены.

Использование объекта, созданного new A("a1") (назовем его A1) в качестве примера.

В момент System.gc() запускается, list ссылка объекта A1 в его внутренней структуре, поэтому не мусор, даже если она не упоминается в a1.

+0

Давайте продолжим обсуждение в чате (http://chat.stackoverflow.com/rooms/88729/discussion-between-cfi-and-derek-fung). Я удалил здесь свои другие комментарии, потому что они больше не применяются или не имеют отношения к этому Q & A – cfi

1

Единственное Указанное правило в отношении объекта достижимости следующим образом (§12.6.1):

достижимый объект любой объект, который можно получить в любой потенциальной продолжения вычислений с любого живого потока.

Изучения кода совершенно ясно, что не объекта не может быть доступен в любых потенциальном продолжении вычислений. Никакая ссылка на какой-либо из них не будет существовать после завершения main; кроме того, System.gc() является последним оператором в программе, и вычисление этого оператора не будет обращаться к тем или иным объектам (у него вообще нет семантики на уровне Java). Таким образом, все объекты на самом деле недоступны в этот момент, реализует ли реальная реализация мусорной коллекции или нет.

+1

Это не последнее утверждение, так как метод заканчивается символом '// some code ... '', который, означает, что больше кода следует за вызовом gc(). И даже если код не следует, имеет ли GC достаточную информацию, чтобы знать, что код не следует и что переменные больше никогда не будут использоваться. и я не думаю, что это так. Я считаю, что ваш ответ действительно прав, если вы придерживаетесь спецификаций, но немного ... nitpicking, потому что на практике AFAIK ничто не может эффективно иметь право на GC при это пункт. –

+0

Я думаю, что это вопрос, связанный с вопросом: это из задания/интервью, и он явно просит получить авторитетный ответ, полученный прямо из спецификации. Поэтому он жизненно зависит от того, что такое «некоторый код». Кстати, он становится гораздо менее nitpicking, когда люди используют свободное рассуждение, чтобы решить, возможно ли OOME в какой-то момент. Например, даже переменные из области видимости могут помешать эффективно недоступным объектам GC'd на практике (это перевернутая часть моего текущего ответа). –

+2

ОК. +1 для напоминания нам о спецификациях. Но, учитывая, что ОП еще не понимает, как ссылки передаются методам и что он, таким образом, может взять интервью у позиции начального уровня, я был бы очень удивлен, если бы интервьюер ожидал такого точного ответа :-) –

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