Go语言中Getter函数与重复值的内存占用对比及函数存储疑问
问题解答
一、内存占用对比:Item2实现更优
在64位系统(Go主流运行环境)下,两种结构体的内存开销可直接计算:
Item[int]结构体:包含1个int(8字节)和1个函数类型字段func(item Item[int]) int。Go中函数值本质是含代码指针和闭包环境指针的结构体,无闭包时环境指针为nil但仍占8字节,因此单个Item[int]实例总大小为8 + 16 = 24字节。Item2[int]结构体:包含2个int字段,单个实例总大小为8 + 8 = 16字节。
当创建100万个实例时:
Item实例总内存占用:1e6 * 24字节 = 24MBItem2实例总内存占用:1e6 * 16字节 = 16MB
即便切片存储的是结构体指针(每个指针8字节),指针切片本身内存开销一致,但Item指向的实例内存明显更大,因此Item2的内存占用更优。
二、Go中函数字段的存储机制
Go语言中,函数类型的值是一个二元结构体:
- 代码指针:指向函数实际执行代码的内存地址;
- 闭包环境指针:指向函数捕获的外部变量(若函数无闭包,该指针为
nil)。
你的代码中,getPriority是未捕获任何外部变量的函数,将它赋值给所有Item实例的getPriority字段时:
- 所有实例的
getPriority字段的代码指针都指向同一内存地址(即getPriority函数的执行代码地址); - 所有实例的闭包环境指针均为
nil。
简言之,这些函数值底层指向的代码完全共享,只是每个结构体实例中存储了一份相同的函数值结构体(包含相同的代码指针和nil环境指针)。
内容的提问来源于stack exchange,提问作者Neo.Mxn0
相关产品推荐
相关产品推荐

