Что такое stop-the-world в garbage collector и зачем он нужен?
Что проверяют
Знаете ли вы устройство сборщика именно в Go, а не общий рассказ про паузы. Вопрос почти всегда ведёт к задержкам в продакшене, поэтому ценится понимание, что происходит под паузой, а что рядом с ней.
Как отвечать
Сборщик в Go конкурентный, трёхцветный, помечающий и подметающий, объекты не перемещает. Основная работа идёт параллельно с приложением, а полная остановка нужна на две короткие фазы: подготовка маркировки с включением барьера записи и завершение маркировки. Обе занимают доли миллисекунды, потому что обхода кучи в них нет.
Зачем вообще останавливать мир: барьер записи должен появиться у всех горутин одновременно, иначе часть изменений указателей пройдёт мимо и живой объект будет помечен мусором. Для этого рантайм доводит каждую горутину до безопасной точки. Гибридный барьер записи снял необходимость повторно сканировать стеки под остановкой, из-за чего пауза раньше росла вместе с числом горутин.
Подметание мир не останавливает вовсе: спаны подметаются лениво, по мере новых выделений. Нагрузку на маркировку рантайм частично перекладывает на приложение через ассисты: горутина, которая много выделяет, обязана отработать долг по маркировке.
Запускается сборка не тогда, когда память закончилась, а по росту кучи относительно живого объёма прошлой сборки, по мягкому лимиту памяти, по таймеру и вручную.
Где спотыкаются
Описывают остановку мира по учебнику о старых сборщиках: мир стоит, пока перебирается вся куча. В Go под паузой не собирается ничего, маркировка и подметание идут конкурентно.
Считают, что горутину можно остановить в любой момент. Остановка возможна только в безопасной точке, и тугой цикл без вызовов функций приходится снимать сигналом, ради чего асинхронное вытеснение и появилось.
Списывают на остановку мира весь провал по хвостовым задержкам. Чаще виноваты ассисты и сам темп выделений: горутина стоит не потому, что мир остановлен, а потому что отрабатывает свою часть маркировки.