这个其实是我在面试的时候经常问的一个问题:“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 字节了。

你搞懂了吗?