> Что происходит в программе при отсутствии доступной памяти (Go)

Уровень: middle · Роль: backend · Категория: Технические вопросы

Компании: Avito

Стек: Go

> Пример ответа

Короткий ответ

В Go при нехватке памяти runtime вызывает фатальную ошибку out of memory и аварийно завершает программу с кодом 2. Это происходит, когда аллокатор не может получить память у операционной системы через mmap или brk. В отличие от C, где malloc возвращает NULL, в Go нет возможности обработать OOM внутри программы - процесс убивается немедленно, без паники и без вызова defer.

Подробное объяснение

Go использует собственный аллокатор на основе tcmalloc. Когда программа запрашивает память, runtime сначала пытается удовлетворить запрос из уже зарезервированных страниц. Если свободных страниц нет, аллокатор обращается к ОС за новыми страницами через mmap.

Если ОС отказывает в выделении памяти (например, из-за лимита ulimit -v, cgroup limit или исчерпания физической памяти и swap), runtime вызывает runtime.throw("out of memory"). Это приводит к немедленному завершению процесса с сообщением в stderr и кодом выхода 2.

Важно: в Go нет механизма перехвата OOM. Даже если вы напишете recover() вокруг аллокации, это не поможет - OOM не является паникой, это фатальная ошибка runtime. Паника возникает только при panic(nil) или явном вызове, но не при нехватке памяти.

Также стоит учитывать, что в Go есть два уровня нехватки памяти:

  • нехватка виртуальной памяти (адресного пространства) - редка на 64-битных системах;
  • нехватка физической памяти - ОС может убить процесс через OOM-killer (SIGKILL), что тоже не перехватывается.

На практике

На практике OOM в Go чаще всего возникает из-за:

  • бесконечного роста слайса или мапы без ограничений;
  • утечки горутин, каждая из которых держит память;
  • слишком большого GOMAXPROCS при ограниченных ресурсах контейнера;
  • неверной оценки размера данных (например, чтение всего файла в память).

Для предотвращения OOM используют:

  • лимиты памяти в контейнерах (cgroup) - но это приводит к SIGKILL, а не к ошибке Go;
  • профилирование с pprof для поиска утечек;
  • ограничение размера структур данных;
  • использование sync.Pool для переиспользования объектов.

Важно: в Go нет try/catch для OOM, поэтому единственный способ - не допускать ситуацию, а не обрабатывать её.

Пример кода

GO
package main
import "fmt"
func main() {
// Бесконечный рост слайса - классический путь к OOM
var data []byte
for {
data = append(data, make([]byte, 1024*1024)...) // 1 MB за итерацию
fmt.Println("allocated:", len(data)/1024/1024, "MB")
}
}

Этот код будет работать, пока не упрётся в лимит памяти, после чего runtime выведет:

runtime: out of memory: cannot allocate 1048576-byte block (6291456 in use)
fatal error: out of memory

Как отвечать на собеседовании

Начните с факта: в Go OOM - фатальная ошибка, процесс завершается. Затем объясните механизм: runtime запрашивает память у ОС, при отказе вызывает throw. Упомяните, что recover не работает, потому что это не паника. Приведите практический пример - бесконечный append. Если спросят про отличие от C - скажите, что в C malloc возвращает NULL, и программист может обработать это, а в Go такой возможности нет. Завершите тем, что профилактика - единственный способ борьбы: лимиты, профилирование, аккуратная работа с большими данными.

Что проверяет интервьюер

Интервьюер проверяет:

  • понимание модели памяти Go и роли runtime;
  • знание разницы между паникой и фатальной ошибкой;
  • осведомлённость о поведении ОС при нехватке памяти (OOM-killer);
  • практический опыт - как вы находили и исправляли утечки памяти;
  • умение объяснить, почему recover не спасает при OOM.

Типичные ошибки

  • утверждение, что OOM можно поймать через recover - это неверно;
  • смешивание OOM с паникой из-за panic("out of memory") - это разные вещи;
  • игнорирование роли ОС - на Linux процесс может быть убит через SIGKILL, и это не ошибка Go;
  • утверждение, что Go автоматически освобождает память при нехватке - GC не спасает от OOM, если память реально нужна;
  • отсутствие упоминания pprof как инструмента диагностики.

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью