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 }
GO
  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的倍数,已经实现了内存对齐。