Go语言数组的内存布局是怎样的?元素地址为何间隔8字节
Go数组固定间隔地址排布的原因
你观察到的地址间隔是Go数组连续内存存储特性的正常表现,注意你看到的地址是十六进制格式,不是十进制:0x288 + 0x8 = 0x290、0x290 + 0x8 = 0x298,全程相邻元素的地址差值固定为8,不存在异常跳变。
核心逻辑
Go语言的数组是定长值类型,采用静态数组经典的连续内存存储方案:
- 数组所有元素在一整块内存中按声明顺序紧密排列,元素之间没有额外的冗余数据、内存空隙
- 相邻元素的地址差值,完全等于单个数组元素的内存占用大小
- 测试代码中数组元素类型为
int,在当前主流的64位操作系统环境下,Go的int类型固定占8字节,因此相邻元素地址差恒为8,和观测结果完全吻合。
这种存储模式的设计优势
- 访问效率极高:定位元素不需要额外的指针跳转,仅通过
数组首地址 + 下标 * 单元素长度就可以直接计算出目标元素的内存地址,查找任意元素的时间复杂度都是O(1) - 内存开销更低:整块连续分配内存不需要额外存储指针类元数据,也不容易产生细碎的内存碎片
- CPU缓存友好:连续内存块更容易被CPU缓存预加载,遍历数组时的读写性能远高于非连续存储结构
测试代码
package main import "fmt" func main() { const a = 1111111111111111111 test := [7]int{a, 1, 33333,4,6,7,7} fmt.Println(&test[0]) fmt.Println(&test[1]) fmt.Println(&test[2]) fmt.Println(&test[3]) fmt.Println(&test[4]) fmt.Println(&test[5]) fmt.Println(&test[6]) }
64位环境典型运行输出
0xc00000e280 0xc00000e288 0xc00000e290 0xc00000e298 0xc00000e2a0 0xc00000e2a8 0xc00000e2b0
补充说明:如果在32位系统运行上述代码,int类型占4字节,此时相邻元素的地址差值会固定为4,底层排布逻辑完全一致。
内容的提问来源于stack exchange,提问作者Faik SEVİM
相关产品推荐
相关产品推荐

