Если JVM продолжает перемещать объекты, когда выполняет GC, как он разрешает ссылки? - PullRequest
20 голосов
/ 27 февраля 2012

Я читаю о настройке JVM, и мне пришло в голову, что JVM продолжает перемещать объекты, когда выполняет GC.Но у Java-объектов есть ссылки друг на друга, которые, как можно было бы предположить, реализованы в виде указателей, но JVM не может пройти через всю кучу после каждого перемещения объектов и обновить все ссылки;конечно, это займет вечность.Так как же он разрешает ссылки, если ссылки не меняются, а физическое расположение объектов?

Я много читал о JVM, но это никогда не объяснялось и даже не намекалось,где угодно.

[ПРАВИТЬ] Моя точка зрения заключается в том, что ссылки являются односторонними вещами.Переход от указателя к указанному является «мгновенным», но обход наоборот потребует полного сканирования кучи.Хотя это возможно, это кажется маловероятным.Если 10K-объекты переживают небольшую коллекцию, сколько времени потребуется для полного сканирования кучи 10K-раз, чтобы обновить ссылки на эти объекты?Должен использоваться какой-то оптимизированный алгоритм или структура.

Ответы [ 5 ]

13 голосов
/ 27 февраля 2012

Если вы действительно интересуетесь тем, как работают сборщики мусора, могу ли я порекомендовать две книги Ричарда Джонса по сборке мусора. Ссылки / ссылки здесь . Это не касается сбора мусора в Java.

(у меня есть копия старой книги, а новая в моем списке покупок.)


Вот простая версия того, как копирующий сборщик решает эту проблему.

Копирующий коллектор работает путем копирования объектов из одного пространства (из-пространства) в другое (в-пространство).

В частности, GC просматривает график достижимых объектов в пространстве «from», начиная с каждого из корней GC. Каждый раз, когда он находит ссылку на узел (в поле экземпляра, статическом поле, стековом фрейме и т. Д.), Он проверяет объект, на который указывает ссылка, чтобы убедиться, что он помечен как посещенный.

  • Если он еще не отмечен, GC выполняет следующие действия:

    1. Он отмечает объект в космосе.
    2. Копирует объект в космос.
    3. Хранит адрес объекта в пространстве в объекте из космоса. (Это похоже на адрес пересылки.)
    4. Он рекурсивно посещает каждое поле ссылки космической копии объекта.

    Результат этой ссылки на космический объект.

  • Если объект уже помечен, ГХ ищет адрес пересылки и возвращает его.

Местоположение (в пространстве или некотором корне GC), откуда GC получил ссылку, затем обновляется указателем на объект в пространстве.

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

Если вы не выполнили вышесказанное, ПОЖАЛУЙСТА, прочитайте один из рекомендованных мной учебников. Они объяснят это намного лучше, чем я. Вы также найдете материал о том, как другие виды GC справляются с этой проблемой.


Java HotSpot GC являются всеми копирующими сборщиками той или иной формы. Вещи становятся немного более сложными, чем мое описание выше для параллельного и параллельного сбора, но механизм «адреса пересылки» является общим для всех из них.

(Существует не так много опубликованных статей или другой общедоступной документации по ГХ HotSpot, и большая часть существующего материала предполагает, что читатель хорошо понимает, как работают современные сборщики мусора.)

4 голосов
/ 27 февраля 2012

JVM не может проходить всю кучу после каждого перемещения объектов и обновлять все ссылки

Я сам не эксперт по GC, но какНасколько я знаю, это более или менее то, что он делает.См., Например, этот текст:

В отличие от этого, копирующий коллектор копирует достижимые объекты в другую область памяти по мере их прохождения.[...] После такого обхода все выжившие объекты находятся в непрерывной области памяти, и все указатели были обновлены, чтобы указывать на новые местоположения объектов .[...] Во время этого процесса GC создает граф объектов для отслеживания «живых» объектов, чтобы он мог обновлять ссылки на любые объекты, которые он перемещает.

(http://wiki.osdev.org/Garbage_collection#Copy_collectors, выделено мое).

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

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

2 голосов
/ 12 марта 2012

Я не совсем уверен, что именно таким образом обрабатываются ссылки на объекты в куче, но я подозреваю, что ссылки на объекты, которые Java VM раздает нашим программам, это НЕ фактические адреса памяти, а внутренние ссылки JVM, которые указывают нафактический адрес в JVM (HashMap или аналогичная структура).Т.е. все объекты, которые ссылаются на objectA, будут иметь ссылки [NOT address] на objectA, когда происходит GC, JVM НЕ нужно обновлять ссылки во всех этих объектах, только фактический измененный адрес в своем собственном HashMap.

1 голос
/ 27 февраля 2012

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

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

Как это происходит, зависит от используемых алгоритмов сборки мусора, но это действительно трудоемкий процесс, и именно поэтому Java (как таковая) не может использоваться в условиях реального времени

0 голосов
/ 29 февраля 2012

Обычно коллекционеры не обходят всю кучу.Они идентифицируют живые объекты и пересекают их.

Например, копирующий коллектор в Hotspot начинается с корней и идентифицирует все живые объекты.Как только живые объекты идентифицированы, они копируются в новое пространство в куче.Пройдя по всем живым объектам, он выполняет необходимые модификации адресов для живых объектов.

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

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

...