这个其实是我在面试的时候经常问的一个问题:“struct 内存对齐最佳实践”。我们先看一个例子:
type Employee struct {
IsActive bool
Age int64
IsMarried bool
Name string
Photo float32
}
我先提前告诉你: bool 是 1 个字节 int64 8个字节 string 16 个字节 float32 4 个字节,那么这个struct 在内存里面总共占用多少个字节 ?
如果回答: 1+8+16+1+4 = 30 字节,那就把问题想简单了。
cpu 从内存里面取数据,还需要cache,cache 是按照cache line 读取数据的。也就是说再x86_64系统中,即便CPU读取一个字节,底层也是读取 8 个字节的。总之是 8 个字节的整数倍。
所以内存里面会对齐 cache line,使用空白填充。
回到我们的问题,我们可以通过 unsafe.SizeOf 方法获取这个 strut 的大小。结果是 :48,因为 IsActive 首先占用 8 个字节,age 本身就占用 8个字节,IsMarried 也占用 8 个字节,name 占用 16 个字节, Photo也占用 8个字节,所以总结是48 个字节。
可以看到上面很多 红色填充的空白空间,导致资源浪费。所以我们需要调整我们的字段顺序,从而合并空白区域。
type Employee struct {
Name string
Age int64
Photo float32
IsActive bool
IsMarried bool
}
我们将 Photo 、IsActive 和 IsMarried 合并到一起,从而充分利用空间。如下:
这样总体的内存占用就从 48 字节 下降到 32 字节了。
你搞懂了吗?