Рубрики
Без рубрики

Экспериментальные сборщики мусора в СПМ

Автор оригинала: Kumar Chandrakant.

1. введение

В этом уроке мы рассмотрим основные проблемы с управлением памятью Java и необходимость постоянно находить лучшие способы ее достижения. Это в первую очередь будет касаться нового экспериментального сборщика мусора, представленного на Java под названием Shenandoah, и того, как он сравнивается с другими сборщиками мусора.

2. Понимание проблем при сборе мусора

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

2.1. Соображения, касающиеся сборщика мусора

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

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

Тем не менее, сладкое место действительно состоит в том, чтобы найти сборщик мусора, который работает с минимальными паузами и обеспечивает высокую пропускную способность — все это с предсказуемым поведением по размеру кучи, который может варьироваться от небольшого до очень большого! Это постоянная борьба, которая с самого начала поддерживала темпы инноваций в сборке мусора Java.

2.2. Существующие сборщики мусора в Java

Некоторые из традиционных сборщиков мусора включают последовательные и параллельные сборщики . Они являются коллекционерами поколений и используют копирование в молодом и маркировку в старом поколении:

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

Коллектор Concurrent Mark Sweep (CMS) , представленный в Java 1.4, является коллектором поколений, параллельным, с низкой паузой. Он работает с копированием в молодом поколении и разметкой в старом поколении:

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

В качестве долгосрочной замены CMS в Java 7 был представлен сборщик Garbage First (G1) . G1-это поколенческий, параллельный, параллельный и постепенно уплотняющийся сборщик с низкой паузой. Он работает с копированием в молодом поколении и марк-компактным в старом поколении:

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

Таким образом, гонка за поиском лучшего сборщика мусора продолжается, особенно такого, который еще больше сокращает время паузы. В последнее время JVM представила серию экспериментальных коллекторов, таких как Z, Epsilon и Shenandoah. Кроме того, G1 продолжает получать все больше улучшений.

Цель на самом деле состоит в том, чтобы как можно ближе подойти к беспаузной Java!

3. Сборщик мусора Шенандоа

Shenandoah – это экспериментальный коллектор, который был представлен в Java 12 и позиционируется как специалист по задержкам . Он пытается сократить время паузы, выполняя большую часть своей работы по сбору мусора одновременно с пользовательской программой.

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

3.1. Структура кучи

Шенандоа, как и G1, является региональным коллекционером. Это означает, что он делит область кучи на набор областей одинакового размера . Область-это в основном единица выделения или восстановления памяти:

Но, в отличие от G1 и других коллекционеров поколений, Шенандоа не делит область кучи на поколения. Поэтому он должен отмечать большинство живых объектов каждый цикл, чего могут избежать коллекционеры поколений.

3.2. Компоновка объекта

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

Shenandoah добавляет дополнительное слово к этому макету объекта . Это служит косвенным указателем и позволяет Шенандоа перемещать объекты без обновления всех ссылок на них. Это также известный как указатель Брукса .

3.3. Барьеры

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

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

Например, операции чтения и записи в объект могут быть перехвачены сборщиком с помощью барьеров:

Шенандоа использует несколько барьеров в разных фазах, таких как барьер SATB, барьер чтения и барьер записи . Мы увидим, где они используются в последующих разделах.

3.4. Модели, эвристика и режимы отказов

Режимы определяют способ работы Shenandoah , например, какие барьеры он использует, а также определяют его эксплуатационные характеристики. Доступны три режима: нормальный/SATB, iu и пассивный. По умолчанию используется режим normal/SATB.

Эвристика определяет, когда должна начинаться коллекция и какие регионы она должна включать|/. К ним относятся адаптивные, статические, компактные и агрессивные, с адаптивной эвристикой по умолчанию. Например, он может выбрать регионы с 60 процентами или более мусора и начать цикл сбора, когда будет выделено 75 процентов регионов.

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

4. Этапы сбора Шенандоа

Цикл сбора Шенандоа состоит в основном из трех этапов: маркировка, эвакуация и обновление ссылок. Хотя большая часть работы на этих этапах происходит одновременно с пользовательской программой, все еще есть небольшие части, которые должны выполняться в режиме остановки мира.

4.1. Маркировка

Маркировка-это процесс идентификации всех объектов в куче или ее частей, которые недоступны . Мы можем сделать это, начав с корневых объектов и пройдя по графу объектов, чтобы найти доступные объекты. Во время обхода мы также присваиваем каждому объекту один из трех цветов: белый, серый или черный:

Маркировка в режиме “остановить мир” проще, но в параллельном режиме она усложняется. Это связано с тем, что пользовательская программа одновременно изменяет график объектов во время выполнения разметки. Шенандоа решает эту проблему с помощью алгоритма моментального снимка в начале (SATB) .

Это означает, что любой объект, который был живым в начале маркировки или который был выделен с начала маркировки, считается живым. Шенандоа использует барьер SATB для поддержания представления SATB кучи.

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

4.2. Очистка и эвакуация

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

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

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

Кроме того, Шенандоа использует барьеры чтения и записи, чтобы гарантировать, что строгий инвариант “в пространство” сохраняется во время одновременной эвакуации. Это означает, что чтение и запись должны происходить из пространства, которое гарантированно переживет эвакуацию.

4.3. Обновление справочной информации

Эта фаза цикла сбора предназначена для обхода кучи и обновления ссылок на объекты, которые были перемещены во время эвакуации :

Этап ссылки на обновление, опять же, в основном выполняется одновременно . Существуют краткие периоды init-update-refs, которые инициализируют фазу ссылки на обновление, и final-update-refs, которые повторно обновляют корневой набор и перерабатывают регионы из набора сбора. Только для них требуется режим остановки мира.

5. Сравнение С Другими Экспериментальными Коллекторами

Shenandoah-не единственный экспериментальный сборщик мусора, который недавно был представлен на Java. Другие включают Z и Эпсилон. Давайте разберемся, как они сравниваются с Шенандоа.

5.1. Z Коллектор

Представленный в Java 11, коллектор Z является коллектором одного поколения с низкой задержкой, предназначенным для очень больших размеров кучи -мы говорим о многотерабайтной территории. Сборщик Z выполняет большую часть своей работы одновременно с пользовательской программой и использует барьер нагрузки для ссылок на кучу.

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

В широком смысле, цели коллекционера Z схожи с целями Шенандоа . Оба они направлены на достижение низкого времени паузы, которое не прямо пропорционально размеру кучи. Однако с Shenandoah доступно больше вариантов настройки, чем с Z-коллектором .

5.2. Коллектор Эпсилона

Epsilon , также представленный в Java 11, имеет совершенно другой подход к сбору мусора. Это в основном пассивный или “неоперативный” коллектор, что означает, что он обрабатывает выделение памяти, но не перерабатывает ее! Поэтому, когда в куче заканчивается память, JVM просто выключается.

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

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

Очевидно, что Эпсилон преследует совершенно иную цель, чем Шенандоа .

6. Заключение

В этой статье мы рассмотрели основы сборки мусора на Java и необходимость ее постоянного совершенствования. Мы подробно обсудили самый последний экспериментальный коллектор, представленный на Яве — Шенандоа. Мы также рассмотрели, как он работает по сравнению с другими экспериментальными коллекторами, доступными на Java.

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