От чего зависит частота запуска сборщика мусора (GC) в Go?

Ответ

Частота сборки мусора (GC) в Go не привязана к фиксированным временным интервалам. Она определяется темпом выделения памяти в приложении.

Ключевое правило: новый цикл GC запускается, когда объем вновь выделенной в куче (heap) памяти достигает определенного порога. Этот порог по умолчанию равен 100% от объема живой (используемой) памяти, которая осталась после предыдущей сборки.

Этим поведением управляет переменная окружения GOGC (по умолчанию 100).

Пример:

  • После сборки мусора в куче осталось 4 МБ живых данных.
  • При GOGC=100 (по умолчанию), следующий GC запустится, когда приложение выделит еще 4 МБ новой памяти.
  • Если установить GOGC=50, GC запустится после выделения 2 МБ.
  • Если GOGC=200, GC запустится после выделения 8 МБ.
// В этом цикле память выделяется очень интенсивно.
// GC будет запускаться многократно прямо во время его выполнения,
// как только объем новой памяти будет достигать порога GOGC.
func allocateMemory() {
    var data [][]byte
    for i := 0; i < 1000; i++ {
        data = append(data, make([]byte, 1024*1024)) // Выделяем по 1 МБ
    }
}

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

Ответ 18+ 🔞

А, ну так, слушай, про сборку мусора в Go. Это ж классика, блядь! Тут главное — не думай, что она по таймеру тикает, как будильник, ёпта. Нет, всё гораздо хитрее, сука.

Вот представь: после каждой уборки у тебя в куче остаётся, допустим, 4 мегабайта живого хлама — твои рабочие данные. Так вот, следующий дворник-мусорщик прибежит не через час, а тогда, когда ты нассоришь ещё столько же нового мусора. По умолчанию, блядь, именно столько — 100%. Это и есть тот самый GOGC=100.

А если ты, хитрая жопа, выставишь GOGC=50, то он начнёт орать «ХВАТИТ СОРИТЬ!» уже после 2 мегабайт нового бардака. Ну а если GOGC=200, то он тебе даст развернуться, насрать аж на 8 мегабайт, и только потом прибежит с метлой. Понимаешь логику? Чем быстрее ты память тратишь, тем чаще тебя будут прерывать эти уборки — волнение ебать, терпения ноль!

Вот смотри, живой пример, пиздец какой наглядный:

// Эта функция — просто конвейер по производству мусора, ей похуй.
func allocateMemory() {
    var data [][]byte
    for i := 0; i < 1000; i++ {
        data = append(data, make([]byte, 1024*1024)) // Выделяем по 1 МБ
    }
}

Представляешь? Каждую итерацию — новый мегабайт в кучу. Так он, сборщик, через каждые несколько таких гигабайтовых «порций» будет вскакивать: «Опять?! Да я только что тут убрался, блядь!». И будет так до конца цикла, ебать его в сраку. Короче, хочешь жить спокойно — не генерируй хлам как сумасшедший. Всё просто, как три копейки.