在下面的代码中:
c := "fool"
d := []byte("fool")
fmt.Printf("c: %T, %d\n", c, unsafe.Sizeof(c)) // 16 bytes
fmt.Printf("d: %T, %d\n", d, unsafe.Sizeof(d)) // 24 bytes
为了确定从 CloudFoundry 接收 JSON 数据所需的数据类型,我测试了上面的示例代码以了解以下内容的内存分配:[]byte
vs string
type.
预计尺寸为string
类型变量c
是 1 字节 x 4 ascii 编码字母 = 4 字节,但大小显示为 16 字节。
For byte
类型变量d
, GO 将字符串作为字符串文字嵌入到可执行程序中。它在运行时使用以下命令将字符串文字转换为字节切片runtime.stringtoslicebyte
功能。就像是...[]byte{102, 111, 111, 108}
预计尺寸为byte
类型变量d
又是 1 个字节 x 4 个 ascii 值 = 4 个字节,但是变量的大小d
显示 24 字节作为其基础数组容量。
为什么两个变量的大小都不是 4 个字节?
Go 中的切片和字符串都是类似结构体的头:
reflect.SliceHeader https://golang.org/pkg/reflect/#SliceHeader:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
reflect.StringHeader https://golang.org/pkg/reflect/#StringHeader:
type StringHeader struct {
Data uintptr
Len int
}
报告的尺寸unsafe.Sizeof() https://golang.org/pkg/unsafe/#Sizeof是这些标头的大小,不包括指向数组的大小:
Sizeof 接受任何类型的表达式 x 并返回假设变量 v 的大小(以字节为单位),就好像 v 是通过 var v = x 声明的一样。该大小不包括 x 可能引用的任何内存。例如,如果 x 是切片,则 Sizeof 返回切片描述符的大小,而不是切片引用的内存的大小。
要获取某个任意值的实际(“递归”)大小,请使用 Go 的内置测试和基准测试框架。详细信息请参见Go中如何获取变量的内存大小? https://stackoverflow.com/questions/44257522/how-to-get-memory-size-of-variable-in-golang/44258164#44258164
对于具体的字符串,请参见Golang 中字符串内存使用情况 https://stackoverflow.com/questions/52851788/string-memory-usage-in-golang/52851967#52851967。所需的完整内存string
值可以这样计算:
var str string = "some string"
stringSize := len(str) + int(unsafe.Sizeof(str))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)