我正在尝试了解有关内存使用的更多信息。对interface{}和struct{}切片进行一些测试,我注意到切片struct{}不分配任何内存,而切片则分配任何内存interface{}。这对我来说没有多大意义,我实际上期望相同的行为(即两者都不分配任何内容)。无论如何,我找不到关于这个特殊案例的任何解释。有人可以解释一下为什么会发生这种情况吗?package mainimport ( "runtime" "fmt")func main() { // Below is an example of using our PrintMemUsage() function // Print our starting memory usage (should be around 0mb) fmt.Println("Start") PrintMemUsage() fmt.Println("") structContainer := make([]struct{}, 1000000) for i := 0; i<1000000; i++ { structContainer[i] = struct{}{} } fmt.Println("With 1kk struct{}") PrintMemUsage() fmt.Println("") nilContainer := make([]interface{}, 1000000) for i := 0; i<1000000; i++ { nilContainer[i] = nil } fmt.Println("With 1kk nil interface{}") PrintMemUsage() fmt.Println("")}// PrintMemUsage outputs the current, total and OS memory being used. As well as the number // of garage collection cycles completed.func PrintMemUsage() { var m runtime.MemStats runtime.ReadMemStats(&m) // For info on each, see: https://golang.org/pkg/runtime/#MemStats fmt.Printf("Alloc = %v KiB", bToMb(m.Alloc)) fmt.Printf("\tTotalAlloc = %v KiB", bToMb(m.TotalAlloc)) fmt.Printf("\tSys = %v KiB", bToMb(m.Sys)) fmt.Printf("\tNumGC = %v\n", m.NumGC)}func bToMb(b uint64) uint64 { return b / 1024}
2 回答
梦里花落0921
TA贡献1772条经验 获得超5个赞
这是因为空结构不包含任何值。
这对于数组或切片来说不是很有用。但它对于地图很有用。没有价值的地图就像一套。您可以插入密钥并测试它们是否存在。正如您所发现的,缺乏价值可以节省空间。
慕无忌1623718
TA贡献1744条经验 获得超4个赞
类型变量interface{}
可以保存任何值。例如,它可以保存整数8
,可以保存string
值"hi"
,可以保存结构值image.Point{X: 1, Y: 2}
以及几乎所有其他内容。
如果您分配一个具有interface{}
其元素类型的切片,则必须分配内存,以便您可以在其元素中存储任何值。当使用make()
分配它时,它的所有元素都将获得元素类型的零值(这是nil
针对interface{}
),但仍然需要分配内存,否则以后将无法设置元素。
另一方面,空结构struct{}
没有字段,它不能保存任何值(除了struct{}
)。当您分配一个具有struct{}
其元素类型的切片时,不需要分配内存,因为您将无法在其中存储任何需要内存的内容。所以不为这种类型分配内存是一个简单而聪明的优化。
- 2 回答
- 0 关注
- 110 浏览
添加回答
举报
0/150
提交
取消