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

Что такое Full Vacuum?

1.6 Junior🔥 162 комментариев
#Основы Go

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

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

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

Что такое Full Vacuum в Go (Garbage Collection)

Full Vacuum (полная очистка) — это специальная фаза сборки мусора (Garbage Collection, GC) в Go, которая выполняется при серьезной нехватке памяти в куче (heap). Эта фаза предназначена для максимального освобождения памяти путем агрессивной дефрагментации и возврата освобожденных страниц операционной системе.

Основное назначение Full Vacuum

В отличие от обычного цикла GC, который фокусируется на освобождении объектов, на которые нет ссылок, Full Vacuum решает две дополнительные задачи:

  1. Сжатие (компактизация) памяти: перемещение ещё "живых" (live) объектов в памяти, чтобы устранить фрагментацию и освободить большие непрерывные блоки памяти.
  2. Возврат памяти ОС: возврат освобожденных после сжатия страниц (обычно кратных 4KB или 8KB, в зависимости от ОС) обратно операционной системе, что уменьшает RSS (Resident Set Size) процесса.

Когда запускается Full Vacuum?

Эта фаза не является частью регулярного цикла сборки мусора. Она активируется в критических ситуациях, определяемых планировщиком GC Go (в runtime/mgcpacer.go). Основной триггер:

  • Сильный дефицит свободной памяти в куче после нескольких обычных циклов GC, когда Go-рантайм видит, что выделенная для кучи память (heap_sys) значительно превышает фактически используемую (heap_inuse), и при этом ОС сигнализирует о нехватке памяти в системе или процесс приближается к лимиту.

Проще говоря, если после нескольких сборок мусора "мусора" мало, но память фрагментирована и удерживается большими, но частично пустыми, span'ами, может быть запущен Full Vacuum.

Техническая реализация

Full Vacuum работает на уровне mspan — структур рантайма, управляющих блоками памяти определенного размера. Процесс можно упрощенно описать так:

// Псевдокод, иллюстрирующий логику
func gcFullVacuum() {
    // 1. Приостановка мира (STW - Stop The World). На этой фазе STW обычно дольше.
    stopTheWorld()

    // 2. Обход всей кучи, идентификация сильно фрагментированных 'mspan'
    for span := range allSpans {
        if span.isFragmented() && span.freePages > threshold {
            // 3. Эвакуация живых объектов из этого span в более плотные участки
            evacuateLiveObjects(span)
            // 4. Помечание span как свободный для возврата ОС
            span.state = mSpanFree
        }
    }

    // 5. Возврат страниц памяти, помеченных как свободные, операционной системе
    sysUnused(freePageMemory)

    // 6. Возобновление мира
    startTheWorld()
}

Влияние на производительность

  • Длительная пауза (STW): Поскольку Full Vacuum перемещает живые объекты, все горутины должны быть остановлены. Это может привести к заметным и долгим (> 1ms, иногда десятки ms) паузам (stop-the-world pauses).
  • Производительность CPU: Сам процесс компактизации и обновления указателей требует значительных вычислений.
  • Польза: Краткосрочные потери в производительности компенсируются уменьшением фрагментации, снижением общего потребления памяти процессом и потенциальным снижением задержек будущих обычных циклов GC.

Как наблюдать и управлять?

  1. Логи GC: В логах, включенных через GODEBUG=gctrace=1, Full Vacuum отображается отдельной строкой с пометкой о возврате памяти.
    gc X @X.XXXs Y%: ... -> Z MB, X ms CPU, ... reclaimed X MB (где reclaimed - большой)
    
  2. Метрики runtime/metrics и runtime.ReadMemStats: Резкое падение HeapSys или HeapIdle может указывать на работу Vacuum.
  3. Управление: Прямого управления нет, но можно влиять опосредованно:
    *   `GOGC` (по умолчанию 100): Меньшее значение ускоряет частоту GC, потенциально снижая потребность в Vacuum.
    *   `GOMEMLIMIT` (Go 1.19+): Установка лимита памяти может заставить рантайм активнее возвращать память ОС, включая Vacuum-фазы.

Практическое значение

Full Vacuum критически важен для долгоживущих Go-сервисов с изменчивой или циклической нагрузкой (например, обработка очередей, кэширование). Без него фрагментация могла бы привести к монотонному росту RSS процесса, даже если реальное использование объектов низкое, что в итоге вызвало бы OOM Kill от системы или облачного провайдера.

Итог: Full Vacuum — это "тяжелая артиллерия" сборщика мусора Go, запускаемая в особых случаях для радикального уменьшения потребления физической памяти процессом ценностью более длительных пауз. Его работа — ключевая причина, почему Go-программы могут эффективно управлять памятью в условиях длительной работы с пиковыми и спадными нагрузками.