Пост канала
- ссылка
Memory Alignment: Как сэкономить гигабайты RAM, просто поменяв строчки местами Вы написали структуру из трех полей: 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. #golang #memory #performance #underhood #optimization 👉 @golang_lib
Открыть в MAX- Просмотры
- 379
- ER
- 1,6%
- Реакции
- 6