Вы написали структуру из трех полей:
bool, int64 и еще один bool. Сколько байт она займет в оперативной памяти?Если вы ответили 10 (1 + 8 + 1) - вы мыслите логично. Но компилятор Go выделит под нее 24 байта. Вы только что отдали 14 байт под пустоту.
В высоконагруженных системах с миллионами объектов в кэше этот нюанс превращается в гигабайты потерянной RAM. Это следствие механизма Memory Alignment (Выравнивания памяти).
Почему 10 байт превращаются в 24?
Процессор (на 64-битной архитектуре) читает память не по одному байту, а «машинными словами» - блоками по 8 байт. Чтобы процессор мог за один такт прочитать тяжелый тип данных вроде
int64, этот тип обязан начинаться с адреса, кратного 8.Если перед ним лежит мелкий тип, компилятор принудительно забивает промежуток пустыми байтами (Padding).
type BadUser struct {
IsActive bool // 1 байт
// + 7 байт пустоты (Padding), чтобы выровнять следующий int64
ID int64 // 8 байт
IsAdmin bool // 1 байт
// + 7 байт пустоты в конце, чтобы размер структуры был кратен самому большому полю
} // Итого: 24 байта
Как это починить? (Золотое правило сортировки)
Располагайте поля в структуре от самых тяжелых к самым легким (от 8-байтовых к 1-байтовым). Это позволит мелким полям плотно "упаковаться" в одно машинное слово.
type GoodUser struct {
ID int64 // 8 байт (идеально ложится в машинное слово)
IsActive bool // 1 байт
IsAdmin bool // 1 байт
// + 6 байт пустоты в конце структуры
} // Итого: 16 байт
Мы сэкономили 33% памяти, просто поменяв строчки местами! Если у вас в in-memory кэше лежит 10 миллионов таких юзеров, вы выиграли почти 80 Мегабайт RAM из воздуха.
🔥 Senior Tip: Не делайте это руками
Сидеть и высчитывать байты в структурах на 40 полей не нужно. Для этого есть стандартный тулинг Go -
fieldalignment.Установите его:
go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@latestЗапустите с флагом фикса в папке с проектом:
fieldalignment -fix ./...Утилита проанализирует все структуры и автоматически перепишет код, расставив поля в оптимальном порядке. Если используете
golangci-lint, включите проверку fieldalignment внутри линтера govet.А у вас структуры растут хаотично или сортируются линтерами на уровне CI? 👇
#golang #memory #performance #underhood #optimization
📲 Мы в MAX
👉 @golang_lib