Який збір сміття використовує Go?


111

Go - це зібраний сміттям мову:

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

Тут йдеться про те, що це збирач сміття, але він не заглиблюється в подробиці, і заміна працює ... все ж цей пункт, здається, не надто оновлений з моменту виходу Go.

Це все-таки розмітка? Це консервативно чи точно? Це покоління?


2
Про довгу дискусію про історію збору сміття Go до липня 2018 року дивіться на blog.golang.org/ismmkeynote
Wildcard

Відповіді:


117

Плани збору сміття Go 1.4+:

  • гібридний колектор стоп-світу / одночасний
  • частина зупинки світу обмежена терміном 10 мс
  • Ядра CPU, призначені для роботи одночасного колектора
  • триколірний алгоритм розмітки та зачистки
  • негенераційні
  • некомплектні
  • повністю точний
  • несе невеликі витрати, якщо програма рухається вказівниками
  • нижча затримка, але, швидше за все, також нижча пропускна здатність, ніж Go 1,3 GC

Оновлення 1.3 збирача сміття на версії Go 1.1:

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

Перевіз сміття 1.1

  • розмітка (паралельна реалізація)
  • негенераційні
  • некомплектні
  • здебільшого точні (крім кадрів стека)
  • стоп-світ
  • представлення на основі растрових зображень
  • нульова вартість, коли програма не виділяє пам'ять (тобто: переміщення покажчиків навколо відбувається так само швидко, як у C, хоча на практиці це працює дещо повільніше, ніж C, оскільки компілятор Go не такий просунутий, як компілятори C, такі як GCC)
  • підтримує фіналізатори на об'єктах
  • немає підтримки для слабких посилань

Перебирайте смітник 1,0:

  • так само, як Go 1.1, але замість того, щоб бути в основному точним, збирач сміття консервативний. Консервативний GC може ігнорувати такі об'єкти, як байт [].

Заміна GC іншою - суперечлива, наприклад:

  • за винятком дуже великих наборів, незрозуміло, чи буде GC поколінь швидшим у цілому
  • пакет "небезпечний" ускладнює реалізацію повністю точної ГК та ущільнення GC

Також поточний збірник сміття має певний ступінь паралелізму, тому він може працювати швидше в багатоядерних системах.
uriel

3
@uriel: Так, я згадував це у 1-му пункті у своїй відповіді - текст "(паралельна реалізація)".

Ця відповідь все ще актуальна?
Кім Стебель

c # сміттєзбірник точний, і в c # як у дорозі ви можете мати посилання на учасника, який потрапив, а c # мати небезпечний режим, але я не впевнений, як це порівняти, щоб перейти на небезпечну реалізацію
skyde

3
Що щодо оновлення цієї відповіді на 1.5.x, щоб зробити хороший журнал історії.
Ісмаїл

32

(Про Go 1,8 - 1 квартал 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 « Іди GC: вирішення проблеми із затримкою у програмі Go 1.5 »)

Єдиною ручкою настройки колектора STW був “GOGC”, відносний приріст купи між колекціями. Налаштування за замовчуванням, 100%, спрацьовує збирання сміття кожного разу, коли розмір купи вдвічі перевищує розмір живої купи порівняно з попередньою колекцією:

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

Час GC в колекторі STW.

Go 1.5 представляє одночасно колектор .
Це має багато переваг у порівнянні зі збором STW, але це надзвичайно важко контролювати зростання купи, оскільки програма може виділяти пам'ять під час роботи сміттєзбірника .

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

(Фото з презентації GopherCon 2015 « Іди GC: вирішення проблеми із затримкою у програмі Go 1.5 »)

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

  • Запускайте колектор занадто рано, і додаток виконає занадто багато сміття, витрачаючи ресурси процесора.
  • Запускайте колектор занадто пізно, і додаток перевищить бажаний максимальний ріст купи.

Досягнення правильного балансу без шкоди для одночасності вимагає обережного кроку до сміттєзбірника.

GC-пейсинг має на меті оптимізувати два аспекти: зростання купи та процесор, що використовується сміттєзбірником.

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

Конструкція темпу GC складається з чотирьох компонентів:

  1. Оцінювач обсягу скануючої роботи, необхідної для циклу GC,
  2. механізм для мутаторів виконувати передбачуваний обсяг скануючої роботи до часу розподілу купи досягає мети,
  3. планувальник фонового сканування, коли мутатор допомагає недостатньо використовувати бюджет процесора, і
  4. пропорційний контролер для тригера GC.

Дизайн врівноважує два різні погляди на час: час процесора та час збирання .

  • Час процесора - це як звичайний настінний годинник, але проходить в GOMAXPROCSрази швидше.
    Тобто, якщо GOMAXPROCSце 8, то вісім CPU секунд проходять кожну стіну секунди, і GC отримує дві секунди часу процесора кожну стіну секунди.
    Планувальник процесора керує часом процесора.
  • Проходження часу купи вимірюється в байтах і рухається вперед по мірі виділення мутаторів.

Взаємозв'язок між часом нагромадження і часом стіни залежить від швидкості розподілу і може постійно змінюватися.
Мутатор допомагає керувати плином часу купи, забезпечуючи завершення передбачуваної роботи сканування до моменту досягнення купи цільового розміру.
Нарешті, контролер тригера створює цикл зворотного зв’язку, який пов'язує ці два погляди часу разом, оптимізуючи як час, так і цілі процесора.


20

Це реалізація GC:

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

З документів у джерелі:

GC працює одночасно з мутаційними потоками, має тип точності (він же точний), дозволяє паралельно працювати декількома потоками GC. Це паралельна мітка та розгортка, що використовує бар'єр запису. Це негенераційне і не ущільнювальне. Виділення здійснюється за допомогою розміру, розділеного на P розподільні області, щоб мінімізувати фрагментацію, усуваючи при цьому блокування в загальному випадку.


8

Перехід на 1.8 GC може розвиватися знову, з пропозицією "Усунути повторне сканування стека STW"

За станом на Go 1.7, єдиним джерелом необмеженого та потенційно нетривіального часу зупинки світу (STW) є повторне сканування стека.

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

Попередні експерименти показують, що це може зменшити час найвищого випадку STW до менше 50 мкс , і такий підхід може зробити практичним повне усунення закінчення позначки STW.

Оголошення тут і ви можете побачити Актуальні зробити це d70b0fe і раніше.


3

Я не впевнений, але я думаю, що поточний (наконечник) GC вже паралельний або, принаймні, це WIP. Таким чином, власність зупинки світу вже не застосовується або не буде найближчим часом. Можливо, хтось інший може уточнити це більш детально.


7
Це стоп-світ. GC потенційно працює паралельно після того, як світ був зупинений. Ви, мабуть, мали на увазі одночасний GC.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.