Объяснение Azul "бесстрашный" сборщик мусора

Я только что прочитал это:

http://www.artima.com/lejava/articles/azul_pauseless_gc.html

Хотя у меня есть некоторый опыт работы с компиляторами, я ничего не делал, связанные с сборкой мусора; для меня большой черный ящик.

Я изо всех сил пытался понять проблемы, упомянутые в статье. Я понимаю проблему (есть пауза при выполнении большинства сборщиков мусора), и я понимаю, что они утверждают, что их реализация не имеет этой проблемы. Но я не понимаю, почему/как проблема происходит в первую очередь (кажется, что это кажется понятным в оригинальном тексте), и поэтому я не понимаю, почему их решение может работать.

Может кто-нибудь объяснить мне:

  • почему сборщики мусора имеют эту паузу вообще
  • почему у Azul gc нет этой проблемы?

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

Спасибо!

Ответ 1

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

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

Итак, решение Azul предлагает следующее: они устанавливают "барьер чтения", который позволяет GC перехватывать разыменование, и таким образом они могут лениво обновлять ссылки, которые фактически используются.

Ответ 2

почему сборщики мусора имеют эту паузу вообще?

GCs работают путем отслеживания доступных блоков кучи, начиная с набора глобальных корней (глобальные переменные,   стеки потоков и регистры процессора). GCs лежат на скользящей шкале от моментального снимка до "на лету".   Snapshot GCs работают из моментального снимка глобальных корней и топологии кучи. GC на лету   инкрементно обновлять свою интерпретацию кучи по мере запуска мутаторов.

Трассировка не "почему сборщики мусора имеют эту паузу в целом", есть большие причины для приостановки: перемещение объекта является доминирующим.

Но до точки "на лету" и "моментальных снимков" и их относительной эффективности: трассировка "на лету" может быть более эффективной, чем трассировки моментальных снимков. В той же работе, о которой вы говорите при описании [VCGC], классифицируется предыдущий, негенеративный Бесполезный коллекционер Azul, как точный трассировщик волнового фронта [3]:

"... Большинство практических коллекционеров используют консервативные абстракции волнового фронта, а не точное определение, приведенное здесь. То есть волновой фронт отслеживается при детализации детализации. Однако точный волновой фронт не просто теоретический и в последнее время используется в аппаратном сборщике для сервера Azul Java, который имеет бит" без пометки "в каждом указателе [2]."

Azul C4 делится этим качеством, но достигает его, используя чистый программный, самовосстанавливающийся барьер чтения LVB.

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

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

почему у Azul gc нет этой проблемы?

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

Как уже отмечалось, если "проблема" была неэффективной из-за действия "на лету" или "моментального снимка", то у C4 ее нет, потому что она является точным индикатором волнового фронта. Кроме того, сборщику Azul C4 не требуется или использовать барьер для чтения аппаратных средств, поскольку он работает на системах с ванильной x86 и Linux и обеспечивает лучшую пропускную способность на этом оборудовании, которое собирают сборщики трассировки на основе снимков (см. Сравнение пропускной способности в [1])..

Однако "проблема" в вопросе была сформулирована как "почему сборщики мусора имеют эту паузу в целом?" Уточненность Wavefront (или нет) имеет мало шансов сделать доминирующие паузы в сборщиках мусора. Параллельные и в основном параллельные (хотя и менее эффективные, чем C4) маркеры существуют, но их коллекторы все еще останавливаются. Проблема в том, что трассировка является лишь частью коллекции. Трассировка только говорит вам, что живое и где оно. Это не дает вам никакой памяти назад, и она, конечно же, не дефрагментирует фрагментированную память. Этот предмет подробно обсуждается в различных научных статьях (см. Множество ссылок из статьи C4 [1]).

Это уплотнение (и подразумеваемое перемещение объекта), которое, похоже, является ахиллесовой пятой в настоящее время отправляющих коллекционеров на серверах JVM, и тем, что по своей сути заставляет их принимать [большие] паузы. Простой акт перемещения даже одного объекта из одного места в другое означает, что вы должны исправить все ссылки, указывающие на этот объект, прежде чем программа их использует. Для большинства торговых коллекционеров это означает приостановленную паузу, которая препятствует запуску приложения при исправлении ссылок.

C4 использует самовосстанавливающийся барьер LVB (новый тип считывающего барьера, введенный в [2] и сильно используемый в [1] только в программной форме), чтобы избежать необходимости исправлять ссылки до того, как приложение будет запущено. Это то, как он избегает паузы, которую в конечном итоге должны взять другие коллекционеры. Качество самовосстановления снижает динамическую стоимость считываемых барьеров на несколько порядков по сравнению с предыдущими барьерами, не связанными с самовосстановлением (такими как барьер в стиле ручейков, используемый в других параллельных компакторах в академических работах, сборщики времени). Результатом этого значительно снижается стоимость чтения-барьера, так это то, что он практичен для использования в коллекциях поколений и на серверах JVM.

[1]: "C4: непрерывно параллельный уплотняющий коллектор" http://dl.acm.org/citation.cfm?id=1993491&dl=ACM&coll=DL&CFID=85063603&CFTOKEN=84074207 [2]: "Алгоритм без пауз GC" http://static.usenix.org/events/vee05/full_papers/p46-click.pdf [3]: "Корректирующее выведение алгоритмов сборочной сборки мусора" www.srl.inf.ethz.ch/papers/pldi06-cgc.pdf

(Грэм Томас, технический менеджер EMEA, Azul Systems)

Ответ 3

почему сборщики мусора имеют эту паузу вообще?

Работает GC, отслеживая доступные блоки кучи, начиная с набора глобальных корней (глобальные переменные, потоковые стеки и регистры процессора). GCs лежат на скользящей шкале от моментального снимка до "на лету". Snapshot GCs работают из моментального снимка глобальных корней и топологии кучи. GC на лету обновляют свою интерпретацию кучи по мере запуска мутаторов.

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

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

почему у Azul gc нет этой проблемы?

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

Ответ 4

Почему сборщик мусора не просто mprotect(region_it's_working_on, PROT_READ) и реализует обработчик SIGSEGV, который обновляет все указатели на доступный объект? Да, вы должны были бы отслеживать все указатели на объект, конечно.