Назовите основные причины утечек и повышенного потребления памяти в Go.

Ответ

Основные причины утечек и высокого потребления памяти в Go — это удержание ссылок на объекты, которые больше не нужны. Вот наиболее частые сценарии:

  1. Глобальные переменные и кэши без очистки. Коллекции (map, slice), объявленные в глобальной области видимости, никогда не будут очищены сборщиком мусора (GC), если из них не удалять элементы.

    // Кэш будет расти бесконечно, если его не очищать
    var globalCache = make(map[string]*BigObject)
  2. "Зависшие" (leaked) горутины. Горутина, заблокированная навсегда (например, при чтении из канала, в который никто никогда не напишет), удерживает в памяти свой стек и все связанные с ним объекты.

    go func() {
        <-time.After(time.Hour) // Горутина "уснет" на час, удерживая память
    }()
    
    go func() {
        select {} // Эта горутина заблокируется навсегда
    }()
  3. Неправильная работа со срезами (slices). Срез, являющийся частью большого базового массива, не дает GC освободить этот массив, даже если сам срез небольшой.

    bigSlice := make([]byte, 1024*1024) // 1MB
    // ... какая-то работа
    smallSlice := bigSlice[:10] // smallSlice использует тот же базовый массив
    // Теперь 1MB памяти не будет освобожден, пока существует smallSlice

    Решение: скопировать нужные данные в новый срез: correctSlice := make([]byte, 10); copy(correctSlice, bigSlice[:10]).

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

  5. Использование defer в длинных циклах. Оператор defer выполняет вызов только при выходе из функции. Внутри цикла это может привести к накоплению ресурсов (файловых дескрипторов, памяти), которые освободятся только по завершении всей функции.

Диагностика: лучший способ найти утечки — профилирование с помощью pprof. Основные инструменты:

  • go tool pprof -http=:8080 http://.../debug/pprof/heap — для анализа распределения памяти в куче.
  • go tool pprof http://.../debug/pprof/goroutine — для поиска зависших горутин.