Что такое аллокатор памяти в Go и каковы его ключевые компоненты?

Ответ

Аллокатор памяти (Memory Allocator) в Go — это часть рантайма (runtime), которая отвечает за управление динамической памятью в куче (heap). Его главная задача — быстро и эффективно выделять и освобождать память для объектов, минимизируя при этом фрагментацию и задержки, связанные с блокировками.

Ключевые цели аллокатора в Go:

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

Основные компоненты архитектуры:

  1. mspan (Memory Span): Базовый блок управления памятью. Это непрерывный участок виртуальной памяти, который делится на страницы (8KB) и может содержать объекты одного размера (size class).
  2. mcache (Memory Cache): Локальный кеш памяти для каждой горутины (точнее, для каждого системного потока P). Он содержит mspan-ы для объектов разных размеров. Поскольку mcache локален для потока, выделение памяти из него происходит без блокировок, что очень быстро.
  3. mcentral (Memory Central): Глобальный кеш mspan-ов для определённого класса размеров. Когда у mcache заканчиваются свободные слоты, он запрашивает новый mspan у mcentral. Доступ к mcentral требует блокировки.
  4. mheap (Memory Heap): Главный управляющий кучей. Он владеет всеми mspan-ами. Если в mcentral нет свободных mspan-ов, он запрашивает новую порцию памяти у mheap. mheap, в свою очередь, при необходимости запрашивает память у операционной системы.

Процесс выделения памяти:

// go:noinline
func createObject() *int {
    p := new(int) // Аллокатор попытается выделить память
    return p
}
  1. Escape Analysis: Компилятор определяет, может ли объект жить на стеке. Если объект "сбегает" (например, возвращается из функции по указателю), он должен быть размещён в куче.
  2. Выделение в куче: Аллокатор сначала ищет свободное место в mcache. Если его нет, он обращается к mcentral, а затем, если нужно, к mheap.

Аллокатор тесно работает со сборщиком мусора (GC), который находит и освобождает неиспользуемые объекты, возвращая память обратно в mspan-ы для повторного использования.