首页 >后端开发 >Golang >为什么 Go 中 `unsafe.Sizeof()` 在 `map[string]bool` 和 `map[string]string` 之间没有显示内存差异?

为什么 Go 中 `unsafe.Sizeof()` 在 `map[string]bool` 和 `map[string]string` 之间没有显示内存差异?

Patricia Arquette
Patricia Arquette原创
2024-12-16 00:35:11715浏览

Why Does `unsafe.Sizeof()` Show No Memory Difference Between `map[string]bool` and `map[string]string` in Go?

Go 中的字符串内存使用

许多开发人员在优化 Go 中涉及映射和字符串的代码时遇到了令人惊讶的观察。映射是 Go 中的基本数据结构,值类型的选择会显着影响性能。

在映射存储大量元素(5000 万)的场景中,每个元素的值可以是“ A”或“B”,在 map[string]string 上使用 map[string]bool 似乎是合乎逻辑的。然而,与预期相反,使用 unsafe.Sizeof() 测量这些映射的内存消耗没有发现任何差异。

理解结果

解开这个谜团的关键明显的悖论在于理解 unsafe.Sizeof() 在 Go 中如何运行。 unsafe.Sizeof() 测量值的浅层大小,这意味着它只考虑值本身的大小,而不考虑值引用的任何内存。

在 Go 中,映射是作为指针实现的,这解释了unsafe.Sizeof() 报告的map[string]bool 和map[string]string 的大小一致。两个映射都只是保存一个指向包含键值对的实际数据结构的指针。

Go 中的字符串更加复杂。它们由包含指向底层字节序列及其长度的指针的标头表示。 unsafe.Sizeof() 测量此标头的大小,无论字符串的长度如何,它都保持不变。

深入研究内存消耗

获取更多要准确测量一张地图的内存需求,就必须深入研究数据结构。这可以通过反射来实现,如 StackOverflow 线程“Go 映射保留多少内存?”中所示。

对于字符串,实际的内存使用量可以计算为字符串的字节长度与字符串的字节长度之和。字符串头的大小。

优化字符串内存

考虑由于内存浪费的可能性是至关重要的到字符串切片。创建字符串切片时,它会继承对原始字符串的支持数组的引用。因此,即使不再使用原始字符串,后备数组仍保留在内存中以支持字符串切片。

总之,优化 Go 中的字符串内存使用涉及了解映射和字符串的底层内存布局,并采用尽量减少不必要的记忆保留的技术。

以上是为什么 Go 中 `unsafe.Sizeof()` 在 `map[string]bool` 和 `map[string]string` 之间没有显示内存差异?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn