Понимание сборки мусора Go

Go

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

что такое сбор мусора

Сборка мусора (англ. Garbage Collection, сокращенно GC) — механизм автоматического управления памятью в информатике. Когда динамическая память на компьютере больше не нужна, ее следует освободить, чтобы освободить место для памяти.Такое управление ресурсами памяти называется сборкой мусора. Сборщик мусора может сильно облегчить работу программиста, а также снизить вероятность ошибок программиста. отВикипедия

вообще говоря,Сборка мусора (GC) — это поток демона, работающий в фоновом режиме, его роль заключается в отслеживании состояния каждого объекта, выявлении и отбрасывании объектов, которые больше не используются, для высвобождения и повторного использования ресурсов.

сбор мусора в ходу

Текущий механизм сборки мусора, используемый Golang,Трехцветный маркер для волосСотрудничатьнаписать барьериВспомогательный ГК, метод трехцветной маркировкиразметкаУсовершенствованная версия .

пометить и подметать

Оригинальный метод разметки делится на два этапа:

  1. отметка. Сначала STP (Stop The World), приостановите все запущенные потоки всей программы и пометьте указанный объект
  2. Очистите объекты, которые не были отмечены, то есть освободите ресурсы памяти, а затем возобновите выполнение потока.

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

трехцветная маркировка

Метод трехцветной маркировки является усовершенствованием этапа маркировки, и принцип заключается в следующем:

  1. В начальном состоянии все объекты белые.
  2. Отсканируйте все корневые объекты из корневого корня (a,b ниже) и отметьте объекты, к которым они относятся, серым цветом (A,B на рисунке)

Итак, что такое корень?

Я прочитал много статей, не объясняя эту концепцию, но вот объяснение: корневая область — это в основном область стека и глобальных данных, где программа работает в текущий момент.

  1. Проанализируйте, ссылается ли затененный объект на другие объекты. Если нет ссылки на другие объекты, пометьте серый объект как черный (A на рисунке выше); если есть ссылка, сделайте его черным, а объект, на который он ссылается, также будет серым (B на рисунке выше относится к D )
  2. Повторяйте шаг 3, пока очередь серых объектов не станет пустой. В это время белый объект является мусором и перерабатывается.

Вы также можете обратиться к следующей анимации, чтобы помочь понять:

Как работает Go GC

Выше приведен алгоритм трехцветной маркировки, используемый GO GC, но он, похоже, не отражает, как уменьшить влияние STW на программу? На самом деле потому чтоБольшая часть обработки Golang GC выполняется параллельно пользовательскому коду..

Пользовательский код может изменять состояние некоторых объектов во время GC.Как реализовать GC и пользовательский код параллельно? Давайте посмотрим на весь процесс работы GC:

  1. Марка: Состоит из двух частей:
  • Отметить Подготовка: Инициализировать задачи GC, включая включение барьера записи (защита от записи) и помощи мутатора (помощь мутатора), подсчет количества задач для корневых объектов и т. д.Этот процесс требует STW
  • GC Drains: просканируйте все корневые объекты, включая глобальный указатель и указатель на стек горутины (G) (G необходимо остановить при сканировании соответствующего стека G), добавьте его в очередь меток (серая очередь) и выполните цикл. через объекты в серой очереди, пока серая очередь не станет пустой.Процесс выполняется параллельно в фоновом режиме
  1. Отметить завершение: завершить работу по маркировке, повторно отсканировать глобальный указатель и стек. Поскольку маркировка и пользовательские программы выполняются параллельно, во время процесса маркировки могут возникать новые выделения объектов и назначения указателей.В это время их необходимо записать через барьер записи и выполнить повторное сканирование для повторной проверки.Этот процесс также будет STW.
  2. Развертка: утилизировать все белые объекты в соответствии с отмеченным результатом,Процесс выполняется параллельно в фоновом режиме
  3. Окончание развертки: подметать непройденный участок, и новый раунд GC может быть запущен только после завершения очистки предыдущего раунда GC.

Что если пользовательская логика изменит ссылочное состояние объекта, который только что был отмечен во время маркировки?

Барьер записи

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

Вспомогательный ГК

Из полного процесса работы сборщика мусора, приведенного выше, видно, что сборщик мусора Golang на самом деле разбрасывает одно время паузы. Исходное выполнение программы может быть "код пользователя --> сборщик мусора большого сегмента --> код пользователя", затем рассеянный В будущем это фактически станет «пользовательский код -> небольшой сегмент GC -> пользовательский код -> малый сегмент GC -> пользовательский код». Что, если коллекции GC не поспевают за скоростью, с которой объекты выделяются пользовательским кодом? Если язык Go обнаружит, что скорость рециркуляции после сканирования не поспевает за скоростью выделения, он все равно приостановит пользовательскую логику.После приостановки пользовательской логики это означает, что новые объекты не появятся, а пользовательский поток будет Приходите и присоединяйтесь к секции сбора мусора, чтобы ускорить сбор мусора. Таким образом, первоначальный параллелизм по-прежнему становится STW, а пользовательский поток все равно должен быть приостановлен, иначе сканирование и повторное использование будут бесконечными и не могут быть остановлены, поскольку вновь выделенный объект выполняется быстрее, чем повторное использование, поэтому такие вещи называется вспомогательной рециркуляцией.

Как сделать настройку GC

Чтобы измерить влияние GC на программу, вы можете обратиться к этой статье,Проблемы отладки производительности с программами Go.

Уменьшите выделение объектов и разумно используйте их повторно; Избегайте преобразования строк и [] байтов;

Когда они будут преобразованы, базовая структура данных будет скопирована, поэтому эффективность gc станет ниже.

Используйте экономно + объединить строку;

Строка — самый простой тип в Go, доступный только для чтения, и для каждой операции с ним создается новая строка. Если это небольшой фрагмент небольшого текста, используйте "+", если это большой объем мелкого текста, используйте strings.Join, если большой объем большого текста, используйте bytes.Buffer.

Условия триггера GC

Есть два условия срабатывания автоматической сборки мусора:

  1. Превышение порога размера памяти
  2. время от времени

Порог управляется переменной gcpercent, которая срабатывает, когда соотношение вновь выделенной памяти к уже используемой памяти превышает gcpercent. Например, после завершения перезапуска использование памяти составляет 5 МБ, тогда время следующего перезапуска наступает, когда выделение памяти достигает 10 МБ. То есть дело не в том, что чем больше памяти выделено, тем выше частота сборки мусора. Что делать, если пороговое значение размера памяти никогда не достигается? В это время GC будет запускаться на фиксированное время.Например, если он не достиг 10M, то GC будет запускаться регулярно (по умолчанию каждые 2 минуты) для обеспечения восстановления ресурсов.

напиши в конце

Хотя в Golang есть механизм автоматической сборки мусора, сборщик мусора не является панацеей.Лучше всего выработать привычку освобождать память вручную: например, вручную освобождать память, которая больше не используется, присваивать объекту значение nil или рассмотреть возможность вызова время выполнения в нужное время. .GC() запускает GC.

В последнее время изучаю пример кода в поддерживаемом го.Друзья новички в яме могут обратить на него внимание.go-programming.

Ссылаться на:

обсуждение строки

Язык Go — сборка мусора GC

Анатомия сборки мусора Голанга

Подробное объяснение механизма сборки мусора Golang

резюме по сбору мусора

Общие алгоритмы GC и Golang GC