Как устроен аллокатор памяти в Go?

Ответ

Аллокатор памяти в Go — это высокопроизводительный компонент рантайма, отвечающий за управление памятью в куче (heap). Он спроектирован для эффективной работы в многопоточных приложениях с минимальными задержками.

Ключевые принципы и компоненты:

  1. Иерархия кэшей памяти: Память распределяется по трехуровневой иерархии для минимизации блокировок:

    • mcache: Локальный кэш памяти для каждого процессора (P). Горутины, выполняющиеся на одном P, могут запрашивать память из mcache без блокировок, что делает аллокацию очень быстрой.
    • mcentral: Центральный пул памяти, общий для всех P. Если в mcache заканчивается память определенного размера, он запрашивает ее у mcentral.
    • mheap: Управляет всей кучей. Если в mcentral нет свободных блоков, он запрашивает новую область памяти (арену) у операционной системы через mheap.

  2. Размерные классы (Size Classes): Объекты группируются по размеру (например, 8, 16, 32 байта). Для каждого класса размеров существует свой список свободных блоков, что позволяет избежать фрагментации и ускоряет поиск подходящего блока.



  3. mspan: Основная структура для управления памятью. Это непрерывный блок страниц памяти (обычно 8KB на страницу), который содержит объекты одного размерного класса. mspan может находиться в mcache, mcentral или mheap.


  4. Разделение на маленькие и большие объекты:

    • Маленькие объекты (< 32KB): Аллоцируются через mcache с использованием размерных классов. Это самый частый случай.
    • Большие объекты (> 32KB): Выделяются напрямую из mheap, минуя mcache и mcentral.

  5. Интеграция со сборщиком мусора (GC): Аллокатор тесно работает с GC. Когда GC освобождает объекты, память не возвращается сразу ОС, а помечается как свободная в соответствующих mspan'ах и может быть переиспользована для новых аллокаций.


Пример аллокации:

type Small struct { a, b int64 } // 16 байт
s := new(Small) // Аллоцируется в mcache для size-class 16 байт

Такая архитектура позволяет Go достигать низкой задержки при выделении памяти и высокой производительности в конкурентной среде.