Ответ
Аллокатор памяти в 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 достигать низкой задержки при выделении памяти и высокой производительности в конкурентной среде.