Как сборщик мусора Java обрабатывает ссылки на себя? - PullRequest
21 голосов
/ 02 января 2009

Надеюсь, простой вопрос. Возьмем, к примеру, Циркулярно-связанный список:

class ListContainer
{
  private listContainer next;
  <..>

  public void setNext(listContainer next)
  {
    this.next = next;
  }
}

class List
{
  private listContainer entry;
  <..>
}

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

Ответы [ 7 ]

23 голосов
/ 02 января 2009

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

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

См. Также страницу Википедии о трассировке сборщиков мусора .

14 голосов
/ 02 января 2009

Циркулярные ссылки - это (разрешимая) проблема, если вы полагаетесь на подсчет ссылок, чтобы определить, мертв ли ​​объект. Ни одна реализация Java не использует подсчет ссылок, AFAIK. Более новые Sun JREs используют смесь нескольких типов GC, все пометки и копирование или копирование.

Подробнее о сборке мусора можно прочитать в Википедии и некоторых статьях о java GC здесь и здесь , например.

7 голосов
/ 02 января 2009

Фактический ответ на этот вопрос зависит от реализации. Sun JVM отслеживает некоторый набор корневых объектов (потоков и т. П.) И, когда ему необходимо выполнить сборку мусора, отслеживает, какие объекты доступны из них, и сохраняет их, отбрасывая остальные. Это на самом деле сложнее, чем допустить некоторую оптимизацию, но это основной принцип. Эта версия не заботится о циклических ссылках: пока живой объект не содержит ссылку на мертвый, он может быть GCed.

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

5 голосов
/ 03 января 2009

В качестве неотвеченного ответа (существующих ответов более чем достаточно), вы можете обратиться к техническому документу о системе сбора мусора JVM, если вы вообще заинтересованы в GC. (Любой, только Google JVM Сборка мусора)

Я был поражен некоторыми из используемых техник, и, читая некоторые концепции, такие как «Eden», я впервые осознал, что Java и JVM действительно могут превосходить C / C ++ по скорости. (Всякий раз, когда C / C ++ освобождает объект / блок памяти, включается код ... Когда Java освобождает объект, он вообще ничего не делает; так как в хорошем ОО-коде большинство объектов создаются и освобождаются практически сразу, это удивительно эффективно.)

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

Примечание: я только что понял, что это вводит в заблуждение. Распределение STACK в C ++ очень быстрое - моя точка зрения заключалась в том, чтобы выделить объекты, которые могут существовать после завершения текущей подпрограммы (я считаю, что это ДОЛЖНЫ быть все объекты - это то, о чем вам не нужно думать, если вы собираетесь думаю в ОО, но в С ++ скорость может сделать это непрактичным).

Если вы размещаете только классы C ++ в стеке, это будет распределение по крайней мере так же быстро, как и в Java.

4 голосов
/ 21 августа 2013

да Java-справка для сборщика мусора!

How?

Существуют специальные объекты, называемые корнями сборки мусора (GC-корнями). Они всегда доступны, как и любой объект, который имеет их в своем корне.

Простое Java-приложение имеет следующие корни GC: * ​​1006 *

  1. Локальные переменные в основном методе
  2. Основная нить
  3. Статические переменные основного класса

enter image description here

Чтобы определить, какие объекты больше не используются, JVM периодически запускает то, что очень метко называется алгоритм разметки и развертки . Работает следующим образом

  1. Алгоритм перебирает все ссылки на объекты, начиная с GC корни и помечает каждый найденный объект как живой.
  2. Вся память кучи, которая не занята отмеченными объектами, утилизирован. Он просто помечен как свободный, по существу, освобожден от неиспользованные предметы.

Таким образом, если какой-либо объект недоступен из корней GC (даже если он самоссылочный или циклический), он будет подвергнут сборке мусора.

4 голосов
/ 02 января 2009

Java собирает любые объекты, которые недоступны. Если ничто иное не имеет ссылки на запись, она будет собрана, даже если она имеет ссылку на себя.

2 голосов
/ 03 января 2009

Просто да. :)

Выезд http://www.ibm.com/developerworks/java/library/j-jtp10283/

Все JDK (от Sun) имеют понятие «достижимость». Если GC не может «достучаться» до объекта, он уходит.

Это не какая-то "новая" информация (вы первыми респондентам великолепны), но ссылка полезна, а краткость - это что-то приятное. :)

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