Подтвердить что ты не робот

Если JVM продолжает перемещать объекты вокруг, когда это делает GC, как он разрешает ссылки?

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

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

[EDIT] Я хочу сказать, что ссылки являются односторонними. Переход от указателя к заостренному является "мгновенным", но для перехода на другой путь требуется полное сканирование кучи. Хотя это возможно, это кажется маловероятным. Если объекты 10K выйдут из небольшой коллекции, сколько времени потребуется, чтобы выполнить полную проверку кучи 10K раз, чтобы обновить ссылки на эти объекты? Должен быть какой-то оптимизированный алгоритм или структура.

4b9b3361

Ответ 1

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

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


Вот простая версия того, как копировальный коллектор справляется с этой проблемой.

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

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

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

    • Он отмечает объект в пространстве.
    • Он копирует объект в космос.
    • Сохраняет адрес объекта в пространстве в пространстве-пространстве. (Это как адрес переадресации.)
    • Он рекурсивно посещает каждое поле ссылки для пространственной копии объекта.

    Результат этого ссылки на объект пространства.

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

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

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

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


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

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

Ответ 2

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

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

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

(http://wiki.osdev.org/Garbage_collection#Copy_collectors, внимание мое).

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

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

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

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