← Назад к вопросам

Как устроен сборщик мусора?

2.7 Senior🔥 81 комментариев
#Производительность и оптимизация

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Принцип работы сборщика мусора в Go

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

Архитектура сборщика мусора

Go использует маркировку и очистку (mark-sweep) с несколькими ключевыми оптимизациями:

  1. Трехцветная маркировка (tricolor mark-and-sweep)
  2. Параллельная маркировка (concurrent marking)
  3. Write barriers для сохранения инвариантов
  4. Поколенческий подход в ограниченной форме

Фазы работы GC

1. Фаза маркировки (Mark Phase)

// Упрощенное представление логики маркировки
func mark(start *Object) {
    worklist := []*Object{start}
    
    for len(worklist) > 0 {
        obj := worklist[len(worklist)-1]
        worklist = worklist[:len(worklist)-1]
        
        if !obj.marked {
            obj.marked = true
            // Рекурсивно помечаем достижимые объекты
            for _, ref := range obj.references {
                worklist = append(worklist, ref)
            }
        }
    }
}

Трехцветный алгоритм:

  • Белые объекты — непосещенные, потенциальный мусор
  • Серые объекты — посещенные, но их потомки не обработаны
  • Черные объекты — полностью обработанные, достижимые

2. Фаза очистки (Sweep Phase)

func sweep(heap []*Object) {
    for _, obj := range heap {
        if obj.marked {
            // Объект достижим - снимаем маркер
            obj.marked = false
        } else {
            // Объект недостижим - освобождаем память
            free(obj)
        }
    }
}

Ключевые особенности GC Go

Параллельность и неблокируемость

  • Основная работа GC выполняется параллельно с программой
  • Короткие stop-the-world паузы только в начале и конце цикла
  • Типичная длительность пауз: 10-100 микросекунд

Write Barriers

Механизм, который отслеживает изменения указателей во время работы GC:

// Псевдокод write barrier
func writePointer(dst, src *Object) {
    // Барьер записывает измененный указатель в очередь
    if gcPhase == marking {
        enqueueGrey(dst)
    }
    *dst = src
}

Управление через GOGC

Параметр GOGC определяет стратегию запуска GC:

  • По умолчанию: GOGC=100 (запуск при 100% росте кучи)
  • Можно отключить: GOGC=off
  • Более агрессивный: GOGC=50

Эволюция GC в Go

  1. Go 1.3 — переход на точный сборщик (precise GC)
  2. Go 1.5 — конкурентный сборщик мусора (значительное сокращение пауз)
  3. Go 1.8 — субмиллисекундные паузы
  4. Go 1.12+ — оптимизация больших куч и сканирования стеков
  5. Go 1.19 — мягкий и жесткий лимиты памяти

Практические аспекты

Профилирование GC

# Включение трассировки GC
GODEBUG=gctrace=1 ./program

# Анализ производительности
go tool pprof -alloc_space http://localhost:6060/debug/pprof/heap

Оптимизация под GC

  • Минимизация количества указателей в структурах
  • Использование пулов объектов для горячих структур
  • Избегание больших глобальных переменных
  • Правильное использование sync.Pool

Сравнение с другими языками

ХарактеристикаGoJava (G1)C# (.NET)
Тип алгоритмаПараллельный mark-sweepПоколенческийПоколенческий
ПаузыСубмиллисекундныеДесятки-сотни мсДесятки мс
УправлениеАвтоматическое + GOGCРазные сборщикиРазные режимы

Проблемы и ограничения

  1. Фрагментация памяти — менее выражена, чем в mark-compact
  2. Циклические ссылки — корректно обрабатываются
  3. Большие объекты — обрабатываются отдельно (large object space)
  4. Потребление CPU — обычно 5-25% от времени выполнения

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

Как устроен сборщик мусора? | PrepBro