1. 例子
  • 首先有如下例子,该例子中定义了一个struct,有3个字段,它们的类型有byte,int32,int64,如果任意排列3个字段,会产生6种组合。
  • 根据unsafe.Sizeof()可以获取struct占用内存,那么是否是1+4+8=13呢?
package main

import (
    "fmt"
    "unsafe"
)

type user1 struct {
    b byte
    i int32
    j int64
}
type user2 struct {
    b byte
    j int64
    i int32
}
type user3 struct {
    i int32
    b byte
    j int64
}
type user4 struct {
    i int32
    j int64
    b byte
}
type user5 struct {
    j int64
    b byte
    i int32
}
type user6 struct {
    j int64
    i int32
    b byte
}

//Mac64位
func main() {
    var u1 user1
    var u2 user2
    var u3 user3
    var u4 user4
    var u5 user5
    var u6 user6
    fmt.Println("u1 size is ", unsafe.Sizeof(u1)) //u1 size is  16
    fmt.Println("u2 size is ", unsafe.Sizeof(u2)) //u2 size is  24
    fmt.Println("u3 size is ", unsafe.Sizeof(u3)) //u3 size is  16
    fmt.Println("u4 size is ", unsafe.Sizeof(u4)) //u4 size is  24
    fmt.Println("u5 size is ", unsafe.Sizeof(u5)) //u5 size is  16
    fmt.Println("u6 size is ", unsafe.Sizeof(u6)) //u6 size is  16
}
  1. 分析
  • 内存对齐影响struct的大小
  • struct的字段顺序影响struct的大小
  1. 内存对齐规则
  • 3.1 对某一具体类型, 对齐值=min(编译器默认对齐值,类型大小Sizeof长度) ,在我的Mac上默认为8,所以最大值不会超过8。
  • 3.2 在字段对齐后,struct本身也要进行对齐, 对齐值=min(默认对齐值,字段类型最大长度)
  • 对齐值 也叫 对齐系数对齐倍数对齐模数
  • 每个 字段 在内存中的 偏移量对齐值的倍数
  1. 以上述代码具体分析
  • byteint32int64类型大小Sizeof长度 为1,4,8,编译器默认对齐值是8,所以byteint32int64 的对齐值是1,4,8。
  • 根据 3.1 对struct user1进行内存对齐,其内存结构如下:

内存分布

  • 根据 3.2对struct本身进行对齐,默认对齐值为8,字段最大类型长度为8,所以结构体的对齐值为8,目前内存长度为16,是8的倍数,已经实现了内存对齐。