До Java 7 экземпляр обновления String
состоял из ссылки на массив char[]
и два поля int
, offset
и length
. Вместе с определенными издержками объекта JVM, по крайней мере, двумя словами для HotSpot, он может объяснить в вашей статистике среднее значение 24 байта на String
.
В отличие от этого, массив char[]
содержит служебные данные, специфичные для JVM, длину, сохраненную как int
, и содержимое переменного размера . Так что наблюдение за значительно большим использованием памяти, например, в среднем 40 байтов на массив char[]
, показанный в вашей статистике, не является чем-то необычным. Не зная больше о вашей конкретной конфигурации JVM, это немного догадка, но если мы предположим 16 байтов для заголовка массива, включая длину и, возможно, заполнение, оставшиеся 24 байта предполагают средний размер массива 12 char
с, что не неразумный.
Начиная с Java 7, обновление 6, поля offset
и length
поля String
пропали, что должно уменьшить размер до 16 байт на экземпляр для большинства конфигураций, что может сэкономить ~ 100 МБ для строки экземпляров. И значительно измените соотношение, чтобы char[]
экземпляров доминировали в куче еще больше.
По этой причине, начиная с Java 9, экземпляры String
состоят только из ссылки на массив byte[]
. Если строка состоит только из символов iso-latin-1, что применимо ко многим строкам в типичных приложениях, она будет использовать только один байт на символ, вдвое уменьшая объем памяти для этих строк (для их массива, если быть точным) , Поскольку за пределами этой кодировки будут также строки с символами, конечно, сохранение не будет таким. Но, возможно, еще ~ 100 МБ для вашего приложения.
Но, тем не менее, принимая во внимание среднюю длину строки, указанную выше, память, используемая этими массивами, будет значительно больше, чем память, используемая экземплярами строк, даже при самых последних реализациях. Это нормально.