unsafe.Sizeof()
не рекурсивно входит в структуры данных, он просто сообщает «мелкий» размер переданного значения.Цитирование из документа:
Размер не включает в себя память, на которую может ссылаться x. Например, если x - это слайс, Sizeof возвращает размер дескриптора слайса,не размер памяти, на которую ссылается срез.
Карты в Go реализованы как указатели, поэтому unsafe.Sizeof(somemap)
сообщит размер этого указателя.
Строки в Goпросто заголовки, содержащие указатель и длину.См. reflect.StringHeader
:
type StringHeader struct {
Data uintptr
Len int
}
Так что unsafe.Sizeof(somestring)
сообщит размер вышеуказанной структуры, который не зависит от длины значения string
(которое является значениемполя Len
).
Чтобы узнать фактические требования к памяти карты («глубоко»), см. Сколько памяти резервируют карты golang? , а также Какполучить объем памяти переменной в Golang?
Go сохраняет в памяти закодированные байтовые последовательности UTF-8 со значениями string
.Встроенная функция len()
сообщает длину байта string
, поэтому в основном объем памяти, необходимый для хранения значения string
в памяти:
var str string = "some string"
stringSize := len(str) + unsafe.Sizeof(str)
Такжене забывайте, что значение string
может быть создано путем нарезки другой, более крупной строки, и, таким образом, даже если на исходную строку больше нет ссылок (и, следовательно, она больше не нужна), больший массив резервных копий все равно потребуется для хранения в памятидля меньшего фрагмента строки.
Например:
s := "some loooooooong string"
s2 := s[:2]
Здесь, даже если требование к памяти для s2
будет len(s2) + unsafe.Sizeof(str) = 2 + unsafe.Sizeof(str)
, тем не менее, весь резервный массив s
будут сохранены.