Ответ
Размер объекта String складывается из размера самого объекта и внутреннего массива для хранения символов. Оценка зависит от реализации JVM (особенно с Java 9 и компактированием строк).
Базовая структура (до Java 8):
- Объект
String: заголовок объекта (16 байт на 64-битной JVM со сжатыми ссылками) + поля (char[] value,int hash,int hash32и др.) ≈ 24-32 байта. - Внутренний массив
char[]: заголовок массива (16 байт) + 2 байта на каждый символ (UTF-16). - Выравнивание (padding): JVM округляет общий размер до кратного 8 байтам.
Пример расчета для строки "Hello" (5 символов):
- Объект
String: ~24 байта. - Массив
char[5]: 16 байт (заголовок) + 5 * 2 = 10 байт (данные) = 26 байт → округляется до 32 байт. - Итого: ~56 байт.
Важные изменения с Java 9+:
Введена оптимизация Compact Strings. Если строка содержит только Latin-1 символы (код <= 255), используется массив byte[] (1 байт на символ).
- Для "Hello" (только Latin-1):
- Объект
String: ~24 байта. - Массив
byte[5]: 16 + 5 = 21 байт → округляется до 24 байт. - Итого: ~48 байт (экономия ~8 байт).
- Объект
Как измерить точно?
Используйте инструменты или библиотеки:
-
JOL (Java Object Layout):
// Добавьте зависимость org.openjdk.jol:jol-core import org.openjdk.jol.vm.VM; import org.openjdk.jol.info.ClassLayout; String str = "Hello"; System.out.println(ClassLayout.parseInstance(str).toPrintable()); - Профилировщики памяти (VisualVM, YourKit, JProfiler).
Вывод: Для грубой оценки ASCII/Latin-1 строки можно использовать формулу: ~40 + 2 * n (Java 8) или ~40 + 1 * n (Java 9+), где n — количество символов.