Какой вид сборки мусора использует Go?

111

Go - это язык со сборкой мусора:

http://golang.org/doc/go_faq.html#garbage_collection

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

Это все еще метка? Это консервативно или точно? Это поколенческое?

user1003432
источник
2
Подробное
Wildcard

Ответы:

117

Планы на сборщик мусора Go 1.4+:

  • гибридная остановка мира / параллельный сборщик
  • остановка мира ограничена крайним сроком 10 мс
  • Ядра ЦП, выделенные для работы параллельного сборщика
  • алгоритм трехцветной маркировки и развертки
  • не связанный с поколением
  • неуплотняющийся
  • полностью точный
  • несет небольшие затраты, если программа перемещает указатели вокруг
  • меньшая задержка, но, скорее всего, и меньшая пропускная способность, чем у Go 1.3 GC

Обновления сборщика мусора Go 1.3 поверх Go 1.1:

  • одновременная развертка (приводит к меньшему времени паузы)
  • полностью точный

Сборщик мусора Go 1.1:

  • mark-and-sweep (параллельная реализация)
  • не связанный с поколением
  • неуплотняющийся
  • в основном точные (кроме кадров стека)
  • останови мир
  • представление на основе битовой карты
  • нулевая стоимость, когда программа не выделяет память (то есть: перемещение указателей происходит так же быстро, как в C, хотя на практике это работает несколько медленнее, чем C, поскольку компилятор Go не так продвинут, как компиляторы C, такие как GCC)
  • поддерживает финализаторы на объектах
  • нет поддержки слабых ссылок

Сборщик мусора Go 1.0:

  • То же, что и Go 1.1, но вместо большей точности сборщик мусора консервативен. Консервативный сборщик мусора может игнорировать такие объекты, как [] byte.

Замена сборщика мусора на другой вызывает споры, например:

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

источник
Также текущий сборщик мусора имеет определенную степень параллелизма, поэтому он может работать быстрее в многоядерных системах.
uriel
3
@uriel: Да, я упомянул об этом в первом пункте своего ответа - тексте «(параллельная реализация)».
Этот ответ все еще актуален?
Ким Стебель
Сборщик мусора в С # точен, а в С #, как и в go, вы можете иметь ссылку на член пораженного объекта, а в С # небезопасный режим, но я не уверен, как он сравнивается с небезопасной реализацией
skyde
3
Как насчет обновления этого ответа с помощью 1.5.x, чтобы сделать хороший журнал истории.
Ismael
32

(Для Go 1.8 - первый квартал 2017 года см. Ниже )

Следующий параллельный сборщик мусора в Go 1.5 включает в себя возможность «ускорять», - сказал gc.
Вот предложение, представленное в этой статье, которое может быть использовано для Go 1.5, но также помогает понять gc в Go.

Вы можете увидеть состояние до 1.5 (Stop The World: STW)

До Go 1.5 в Go использовался параллельный коллектор остановки мира (STW).
Хотя у коллекции STW много недостатков, она, по крайней мере, имеет предсказуемое и контролируемое поведение роста кучи.

https://40.media.tumblr.com/49e6556b94d75de1050c62539680fcf9/tumblr_inline_nr6qq8D9FE1sdck2n_540.jpg

(Фотография с презентации GopherCon 2015 « Go GC: решение проблемы задержки в Go 1.5 »)

Единственной ручкой настройки для коллектора STW была «GOGC», относительный рост кучи между коллекциями. Параметр по умолчанию, 100%, запускал сборку мусора каждый раз, когда размер кучи удваивался по сравнению с размером активной кучи, как при предыдущей сборке:

https://docs.google.com/drawings/image?id=sLJ_JvGfPfPnojLlEGLCWkw&rev=1&h=113&w=424&ac=1

Время ГХ в коллекторе STW.

Go 1.5 представляет параллельный сборщик .
Это имеет много преимуществ по сравнению со сборкой STW, но усложняет управление ростом кучи, поскольку приложение может выделять память во время работы сборщика мусора .

https://40.media.tumblr.com/783c6e557b427a5c023520578740eb94/tumblr_inline_nr6qqpmaJx1sdck2n_540.jpg

(Фотография с презентации GopherCon 2015 « Go GC: решение проблемы задержки в Go 1.5 »)

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

  • Слишком рано запустить сборщик, и приложение будет выполнять слишком много сборок мусора, тратя ресурсы ЦП.
  • Запустите сборщик слишком поздно, и приложение превысит желаемый максимальный рост кучи.

Достижение правильного баланса без ущерба для параллелизма требует аккуратной синхронизации сборщика мусора.

Скорость сборки мусора направлена ​​на оптимизацию по двум направлениям: рост кучи и использование ЦП сборщиком мусора.

https://docs.google.com/drawings/image?id=sEZYCf7Mc0E0EGmy4gho3_w&rev=1&h=235&w=457&ac=1

Схема стимуляции ГХ состоит из четырех компонентов:

  1. оценка объема сканирования, который потребуется для цикла ГХ,
  2. механизм, позволяющий мутаторам выполнять предполагаемый объем работы по сканированию к тому моменту, когда выделение кучи достигает целевого значения кучи,
  3. планировщик для фонового сканирования, когда мутатор помогает недоиспользовать бюджет ЦП, и
  4. пропорциональный контроллер для триггера ГХ.

Дизайн уравновешивает два разных взгляда на время: время процессора и время кучи .

  • Процессорное время похоже на время стандартных настенных часов, но проходит в GOMAXPROCSразы быстрее.
    То есть, если GOMAXPROCSравно 8, то восемь секунд процессора проходит каждую секунду стены и GC получает две секунды процессорного времени каждую секунду стены.
    Планировщик ЦП управляет временем ЦП.
  • Время кучи измеряется в байтах и ​​продвигается вперед по мере выделения мутаторами.

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

VonC
источник
20

Это реализация GC:

https://github.com/golang/go/blob/master/src/runtime/mgc.go

Из документов в источнике:

Сборщик мусора работает одновременно с потоками мутатора, точен по типу (он же точен), позволяет нескольким потокам сборщика мусора работать параллельно. Это одновременная отметка и очистка, использующая барьер записи. Он не связан с поколениями и не сжимается. Распределение выполняется с использованием размера, разделенного на области распределения P, чтобы минимизировать фрагментацию и устранить блокировки в общем случае.

berdario
источник
8

Go 1.8 GC может снова развиваться с предложением «Устранить повторное сканирование стека STW»

Начиная с Go 1.7, единственным оставшимся источником неограниченного и потенциально нетривиального времени остановки (STW) является повторное сканирование стека.

Мы предлагаем устранить необходимость в повторном сканировании стека, переключившись на гибридный барьер записи, который сочетает в себе барьер записи удаления в стиле Yuasa [Yuasa '90] и барьер записи вставки в стиле Дейкстры [Dijkstra '78] .

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

Объявление здесь и вы можете увидеть Актуальные совершить это d70b0fe и раньше.

VonC
источник
3

Я не уверен, но я думаю, что текущий (подсказка) GC уже является параллельным или, по крайней мере, это WIP. Таким образом, свойство stop-the-world больше не применяется или не будет применяться в ближайшем будущем. Возможно, кто-то другой сможет прояснить это более подробно.

jnml
источник
7
Это остановка мира. GC потенциально работает параллельно после остановки мира. Вы, вероятно, имели в виду параллельный сборщик мусора.