GoLang - выделение памяти - [] байт против строки - PullRequest
2 голосов
/ 29 апреля 2019

В следующем коде:

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

Чтобы определить тип данных, необходимый для получения данных JSON из CloudFoundry, я тестирую приведенный выше пример кода, чтобы понять распределение памяти для типа []byte против string.


Ожидаемый размер string переменной типа c равен 1 байту x 4 буквы в кодировке ascii = 4 байта, но размер показывает 16 байтов.

Для переменной типа byte d GO встраивает строку в исполняемую программу как строковый литерал. Он преобразует строковый литерал в фрагмент байта во время выполнения с помощью функции runtime.stringtoslicebyte. Что-то вроде ... []byte{102, 111, 111, 108}

Ожидаемый размер переменной типа byte d снова равен 1 байту x 4 значения ascii = 4 байта, но размер переменной d показывает 24 байта как основную емкость массива.


Почему размер обеих переменных не равен 4 байтам?

1 Ответ

7 голосов
/ 29 апреля 2019

И слайсы, и строки в Go являются структурно-подобными заголовками:

reflect.SliceHeader:

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

reflect.StringHeader:

type StringHeader struct {
        Data uintptr
        Len  int
}

Размеры, сообщаемые unsafe.Sizeof(), представляют собой размеры этих заголовков, исключая размер указанных массивов:

Sizeof принимает выражениеx любого типа и возвращает размер в байтах гипотетической переменной v, как если бы v было объявлено через var v = x. Размер не включает в себя память, на которую может ссылаться x. Например, если x является слайсом, Sizeof возвращает размер дескриптора слайса, а не размер памяти, на которую ссылается слайс.

Чтобы получить фактический («рекурсивный») размер некоторого произвольного значения, используйте встроенную платформу тестирования и тестирования Go.Подробнее см. Как получить объем памяти переменной в Golang?

Специально для строк см. Использование памяти строк в Golang .Полная память, требуемая значением string, может быть вычислена следующим образом:

var str string = "some string"

stringSize := len(str) + unsafe.Sizeof(str)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...