Почему размер структуры памяти не соответствует моим ожиданиям? - PullRequest
0 голосов
/ 12 ноября 2019

Я инициализировал структуру и вычислил память, что не соответствует моим ожиданиям.

код:

type Man struct {
Name     string
Money    int
Age      int32
}

func main() {

m := Man{Name:"james", Money:1000000, Age:30}

fmt.Println("man size:", unsafe.Sizeof(m))
fmt.Println("name size:", unsafe.Sizeof(m.Name))
fmt.Println("money size:", unsafe.Sizeof(m.Money))
fmt.Println("age size:", unsafe.Sizeof(m.Age))
}

результат:

man size: 32
name size: 16
money size: 8
age size: 4

Результат моего ожидаемого размера «мужчина» равен 16 + 8 + 4 = 28, но факт равен 32

С нетерпением ждем вашей помощи!

Ответы [ 2 ]

7 голосов
/ 12 ноября 2019

Размер и гарантии выравнивания :

Для числовых типов гарантируются следующие размеры:

type                                 size in bytes

byte, uint8, int8                     1
uint16, int16                         2
uint32, int32, float32                4
uint64, int64, float64, complex64     8
complex128                           16

гарантированы следующие минимальные свойства выравнивания:
1. Для переменной x любого типа: unsafe.Alignof (x) не меньше 1.
2. Для переменной x типа struct: unsafe.Alignof (x)является наибольшим из всех значений unsafe.Alignof (xf) для каждого поля f из x, но не менее 1.
3. Для переменной x типа массива: unsafe.Alignof (x) совпадает с выравниваниемпеременной типа элемента массива.
Тип структуры или массива имеет нулевой размер, если он не содержит полей (или элементов, соответственно), размер которых больше нуля. Две разные переменные нулевого размера могут иметь один и тот же адрес в памяти.

Затем прочитайте их:
Схемы памяти
Заполнение трудно - ДэйвCheney

Объяснение на 64-битной машине:

Ваш тип является struct, и его размер зависит от того, как были определены базовые типы. Две структуры с одинаковыми полями, но разным порядком, могут иметь разные размеры. Размер структуры учитывается в соответствии с правилами заполнения и выравнивания.

Struct alignment

Примечание: каждое цветное поле составляет один байт.
Попробуйте здесь и отредактируйте структуру, затем нажмитеКнопка Ask в верхней части страницы.

4 голосов
/ 12 ноября 2019

Вы можете найти этот размер объяснителя полезным;У меня конечно есть.

Для примера в вашем комментарии , с полями типа bool, uint32, bool, uint32, uint8, uint32и uint8, go использует 4-байтовое выравнивание, потому что ни один из отдельных типов не больше этого. Каждое 1-байтовое поле в этом примере заканчивается использованием четырех байтов, поскольку каждое из них находится только рядом с 4-байтовыми типами. Каждое поле заканчивается использованием четырех байтов, в общей сложности 28. Если вы переставите поля так, чтобы все четыре однобайтовых поля были в начале или в конце, все они могли быть упакованы в одно 4-байтовое окно, поэтомувся структура занимает всего 16 байтов.

Для примера в исходном сообщении go использует 8-байтовое выравнивание, поскольку для одного из полей структуры требуется как минимум восемь байтов, поэтому поля используют 16, 8 и 8байт, соответственно, в общей сложности 32. В этом случае нет необходимости переставлять поля, потому что только одно из них меньше, чем выравнивание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...