Ответ
Аллокатор памяти в Go — это высокопроизводительный компонент рантайма, отвечающий за управление памятью в куче (heap). Он спроектирован для эффективной работы в многопоточных приложениях с минимальными задержками.
Ключевые принципы и компоненты:
Иерархия кэшей памяти: Память распределяется по трехуровневой иерархии для минимизации блокировок:
mcache
: Локальный кэш памяти для каждого процессора (P). Горутины, выполняющиеся на одном P, могут запрашивать память изmcache
без блокировок, что делает аллокацию очень быстрой.mcentral
: Центральный пул памяти, общий для всех P. Если вmcache
заканчивается память определенного размера, он запрашивает ее уmcentral
.mheap
: Управляет всей кучей. Если вmcentral
нет свободных блоков, он запрашивает новую область памяти (арену) у операционной системы черезmheap
.
Размерные классы (Size Classes): Объекты группируются по размеру (например, 8, 16, 32 байта). Для каждого класса размеров существует свой список свободных блоков, что позволяет избежать фрагментации и ускоряет поиск подходящего блока.
mspan
: Основная структура для управления памятью. Это непрерывный блок страниц памяти (обычно 8KB на страницу), который содержит объекты одного размерного класса.mspan
может находиться вmcache
,mcentral
илиmheap
.Разделение на маленькие и большие объекты:
- Маленькие объекты (< 32KB): Аллоцируются через
mcache
с использованием размерных классов. Это самый частый случай. - Большие объекты (> 32KB): Выделяются напрямую из
mheap
, минуяmcache
иmcentral
.
- Маленькие объекты (< 32KB): Аллоцируются через
Интеграция со сборщиком мусора (GC): Аллокатор тесно работает с GC. Когда GC освобождает объекты, память не возвращается сразу ОС, а помечается как свободная в соответствующих
mspan
'ах и может быть переиспользована для новых аллокаций.
Пример аллокации:
type Small struct { a, b int64 } // 16 байт
s := new(Small) // Аллоцируется в mcache для size-class 16 байт
Такая архитектура позволяет Go достигать низкой задержки при выделении памяти и высокой производительности в конкурентной среде.