Java выполняет GC рекурсивно? - PullRequest
2 голосов
/ 14 июня 2011

Возможно, это глупый вопрос.
Когда объект помечен для сборки мусора, java также помечает содержащиеся объекты для сборки мусора?

Я имею в виду,

class ContainerClass {
    ContainedClass obj1, obj2;  
    //Constructor
    ContainerClass() {
    obj1 = new ContainedClass ();
    obj2 = new ContainedClass ();
    }
  // main
    public static void main( String args[]) {
        ContainerClass  c = new ContainerClass();
        c = null ; // c is mared for GC. The question is c.obj1 and c.obj2 is also marked?
    }   
}

Ответы [ 5 ]

5 голосов
/ 14 июня 2011

Да, если только объект ContainerClass имеет ссылки на них, то объекты ContainedClass станут пригодными для сбора мусора в тот же момент, когда сам объект ContainerClass станет приемлемым. 1006 *

Обратите внимание, что фактическая коллекция этих объектов может происходить независимо.

3 голосов
/ 14 июня 2011

Ваш вопрос в некотором роде задом наперед. Объекты не помечаются для сбора, а помечаются для хранения.

Сборщик мусора отмечает объекты, которые все еще используются, начиная с активных кадров стека и всех статических переменных и т. Д., Следуя ссылкам, которые он находит. Каждый объект, который находит сборщик мусора, помечается как используемый и не будет собран.

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

(Это, безусловно, верно для сборщика мусора с меткой и зачисткой, который используется по умолчанию для большинства виртуальных машин Java. Другие сборщики мусора могут вести себя по-разному.)

1 голос
/ 14 июня 2011

Объект готов к сборке мусора, если нет живого потока, который прямо или косвенно хранит ссылку на объект. Так что да, содержащиеся объекты также готовы к сборке мусора.

0 голосов
/ 14 июня 2011

Java выполняет GC рекурсивно?

Нет. Приличный сборщик мусора не использует простую рекурсию для маркировки. Если это так, то для маркировки длинных связанных списков потребуется алгоритм маркировки, чтобы использовать его для очень глубокого стека. Это было бы серьезной проблемой.

Существует ряд стратегий, которые разработчики GC могут использовать, чтобы избежать чрезмерной рекурсии:

  • На самом деле вы не используете рекурсию. Вы используете стек меток и итеративный алгоритм ... который более экономичен.
  • Трюки могут быть использованы для минимизации глубины стека при обходе глубоких списков ... если вы знаете, где находится глубина; например это поле next.
  • У Кнута и Бёма-Демерс-Вайзера есть способы справиться с переполняющейся стопкой меток, которая включает в себя разлив стопки и затем сбор кусков.
  • Алгоритм Дойча-Шорра-Уэйта использует реверсирование указателей и, следовательно, вообще не имеет стека меток.
  • и т. Д.

Если вам нужны более подробные сведения, обратитесь к «Сборщик мусора: алгоритмы для автоматического динамического управления памятью» Ричарда Джонса и Рафаэля Линса, 1996. (Существует новая книга GC под названием «Мусор» Сборник «Искусство автоматического управления памятью» от Ричарда Джонса, Энтони Хоскинга и Элиота Мосса, который должен выйти в конце этого года !!)

(Nit pick: GC не помечает объекты для сбора мусора. Он помечает их как не-мусорные ... и выбрасывает объекты, которые НЕ помечены.)

0 голосов
/ 14 июня 2011

Для вас особый пример: да, содержащиеся объекты будут помечены для gc, но нет, потому что контейнер собран.Они помечены, потому что после контейнера не существует, никакие другие объекты не содержат ссылки на экземпляры ContainedClass.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...