Сборка "мусора" в Java

На слайдах я пересматриваю от него, говорит следующее:

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

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

Трассировка включает идентификацию живые объекты только, когда необходимо освободить пространство – перемещение стоимости от общего доступа до времени, в которое GC работает, обычно только когда Вы вне памяти.

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

Спасибо

9
задан Donal Fellows 30 May 2010 в 23:57
поделиться

5 ответов

Подсчет ссылок не выявляет циклических структур ...

Допустим, у вас есть два объекта O1 и O2. Они ссылаются друг на друга: O1 -> O2 и O2 -> O1, и никакие другие объекты не ссылаются на них. У них обоих будет счетчик ссылок 1 (один реферер).

Если ни O1, ни O2 недоступны из корня GC, они могут быть безопасно удалены сборщиком мусора. Это не обнаруживается при подсчете ссылок, поскольку у них обоих счетчик ссылок> 0.

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

... но он может постепенно освобождать место.

Инкрементальная часть относится к тому факту, что вы можете быстро собрать мусор для некоторых объектов, на которые есть 0 ссылки, без проблем прервать их и продолжить в другое время.

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

5
ответ дан 3 November 2019 в 04:41
поделиться
  1. Простой подсчет ссылок не может разрешить случаи, когда A относится к B, а B относится к A. В этом случае и A, и B будут иметь счетчик ссылок 1 и не будут собираться, даже если есть других ссылок нет.
  2. Подсчет ссылок может освободить пространство немедленно, когда счетчик ссылок какого-либо объекта становится равным 0. Нет необходимости ждать цикла сборки мусора, сканировать другие объекты и т. Д. Таким образом, в некотором смысле он работает постепенно, поскольку он освобождает пространство из объектов один за другим. один.
1
ответ дан 3 November 2019 в 04:41
поделиться

Представьте, что у вас есть три объекта (A, B, C): A имеет ссылку на B, B имеет ссылку на C, а C имеет ссылку на A.Но ни один другой объект не имеет ссылки на один из них. Это независимая циклическая структура. Использование традиционного подсчета ссылок не позволит сборщику мусора удалить цикл, потому что на каждый объект по-прежнему ссылаются. Но до тех пор, пока ни у кого нет ссылки на один из трех, они могут / должны быть удалены. Я предполагаю, что постепенное освобождение пространства означает, что подсчет ссылок работает при поиске экземпляров без ссылок, без циклов и т. Д.

0
ответ дан 3 November 2019 в 04:41
поделиться

"не обнаруживает циклические структуры"

Допустим, у меня есть объект A. A нуждается в другом объекте под названием B для выполнения своей работы. Но B нуждается в другом объекте под названием C для выполнения своей работы. Но C по какой-то причине нуждается в указателе на A. Таким образом, граф зависимостей выглядит так:

A -> B -> C -> A

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

Допустим, наша основная программа во время выполнения создала структуру, подобную этой, и у основной программы был указатель на A, в результате чего счетчик A стал равен двум. Что произойдет, если эта структура выпадет из области видимости? Счетчик ссылок A уменьшается до единицы.

Но обратите внимание! Теперь A, B и C имеют количество ссылок, равное единице, хотя они недоступны из основной программы. Таким образом, это утечка памяти. В Википедии есть подробности о том, как решить эту проблему.

"it can reclaim space incrementally"

Большинство сборщиков мусора имеют период сбора, во время которого они приостанавливают выполнение и освобождают объекты, которые больше не используются. В системе mark-and-sweep это шаг зачистки. Недостатком является то, что в периоды между чистками память продолжает расти и расти. Объект может перестать использоваться почти сразу после его создания, но он никогда не будет освобожден до следующей очистки.

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

Конечно, такой инкрементализм может иметь свои подводные камни, а именно, что может быть менее затратным выполнять массовый GC, а не множество маленьких, но это определяется конкретной реализацией.

1
ответ дан 3 November 2019 в 04:41
поделиться

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

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

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

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

0
ответ дан 3 November 2019 в 04:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: