Golang — сборка мусора в целом

Как мы все знаем, golang является языком со сборкой мусора, как и другие языки, такие как java, python , C# и т.д. Golang — это статически типизированный язык со сборкой мусора.

Что такое сборка мусора и зачем она нужна

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

В программах на SML (и в большинстве других языков программирования) можно создавать мусор: выделенное пространство, которое больше не используется программой.

Когда программа выполняется на вашем компьютере, есть две важные части памяти, которые она использует: Стек и Куча.

Вышеприведенный код имеет тип RandomBox, а GenerateRandomBox() — это функция, которая возвращает тип RandomBox. Ссылка была присвоена в стеке, а данные struct находятся в куче. Golang использует Escape Analysis, чтобы определить это.

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

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

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

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

Что происходит в процессе сборки мусора

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

Mark Setup

  • что означает, что компилятор пытается остановить все, буквально это называется «остановить мир». В это время в вашем приложении ничего не делается.
  • Сначала включается барьер записи, который означает, что ничего не будет записано в память, когда этот барьер включен (остановка всех go-программ). Компилятор должен сделать это, чтобы убедиться, что ваше приложение не потеряет никаких данных.

  • После выполнения STW и включения барьера записи сборщик переходит к следующей фазе.

Маркировка

В этой фазе происходит следующее

  • Осмотр stacks для поиска корневого указателя в heap.
  • Обход heap и проверка, не используются ли они до сих пор.

Коллектор также использует go-routine, как и мы, и он берет 25% доступных go-routine и назначает их себе. То есть, исходя из нашего предыдущего примера, 1 поток будет выделен коллектору.

Теперь, если коллектор обнаружит, что при выполнении этой задачи у него может закончиться память, потому что какая-то другая go-routine выделяет больше, чем может выделить. Тогда он выберет эту go-routine и попросит ее помочь с маркировкой. Этот процесс называется Mark Assist

Завершение разметки

Здесь коллектор снова выполнит STW, отключит барьер записи, выполнит некоторую очистку и рассчитает следующее расписание сборки мусора.

Примечание: Цель состоит в том, чтобы сохранить STW в пределах 100 мс для каждой коллекции, которую необходимо выполнить.

Когда процесс Mark Termination завершен (STW и барьер записи выключены), приложение снова начинает работать со всеми доступными потоками ОС.

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

Развенчание мифов: Подметание не является частью сборки мусора, оно происходит вне процесса сборки.

Подметание

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

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

Триггеры сборки мусора

  • Первая метрика, за которой будет следить сборщик мусора, — это рост heap. По умолчанию он запускается, когда размер кучи удваивается. (код)
  • Вторая метрика, за которой следит сборщик мусора, — это задержка между двумя сборщиками мусора. Если она не срабатывала более двух минут, будет принудительно запущен один цикл. (код)
  • Память приложения также может вызвать сборку мусора — это функция runtime.mallocgc, которая во время выполнения разделяет объекты на heap на микрообъекты, маленькие объекты и большие объекты по размеру. Создание каждого из этих трех объектов может запустить новый цикл сборки мусора.

  • Вручную его можно запустить, вызвав gc().

Ручки сборщика GC

В отличие от java было решено, что разработчик golang не должен настраивать сборщик мусора при переходе на другое оборудование. Поэтому они предоставили только один конфигурационный конфиг под названием SetGCPercentage или GOGC переменная окружения. По умолчанию для GOGC установлено 100%.

GC Pacer

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

Надеюсь, что этот блог смог предоставить немного больше информации о процессе сборки мусора и о том, как он реализован в Golang.

Счастливого обучения!!!

Оцените статью
devanswers.ru
Добавить комментарий