Сколько памяти использует строка в Java 8?

Я много читал о распределении памяти для строк в последнее время и не могу найти никаких подробностей, если все то же самое с Java 8.

Сколько пространства памяти будет использовать String как "Alexandru Tanasescu" в Java 8? Я использую 64-битную версию.

Java7 или ниже

Минимальное использование памяти строк:

 (bytes) = 8 * (int) ((((no chars) * 2) + 45) / 8) 

Так

 80 = 8 * (int) ((((19) * 2) + 45) / 8) 

Понимание использования памяти строк ( SOURCE )

Чтобы понять приведенный выше расчет, нам нужно начать с просмотра полей объекта String. Строка содержит следующее:

  • массив символов – таким образом отдельный объект, содержащий фактические символы;
  • целочисленное смещение в массив, с которого начинается строка;
  • длина строки;
  • другой int для кэшированного вычисления hash-кода.

Это означает, что даже если строка не содержит символов, для массива символов char потребуется 4 байта плюс 3 * 4 = 12 байтов для трех полей int и 8 байтов заголовка объекта. Это дает 24 байта (что кратно 8, так что до сих пор нет «заполняющих» байтов).

Затем (пустой) char-массив потребует еще 12 байт (для массивов требуется 4 байта для хранения их длины), плюс в этом случае 4 байта заполнения, чтобы довести память, используемую объектом массива char, до кратного 16. Таким образом, пустая строка использует 40 байт.

Если String содержит, скажем, 19 символов, то сам объект String по-прежнему требует 24 байта. Но теперь для массива char требуется 12 байт заголовка плюс 19 * 2 = 38 байт для семнадцати символов. Так как 12 + 38 = 50 не кратно 8, нам также нужно округлить до следующего кратного 8 (56). Таким образом, наша 19-символьная String будет использовать 56 + 24 = 80 байт.


Java8.

Java 8 больше не имеет offset и length . Только hash и CharArray .
@Thomas Jungblut

  • массив символов – таким образом отдельный объект, содержащий фактические символы;
  • целочисленное смещение в массив, с которого начинается строка;
  • длина строки;
  • другой int для кэшированного вычисления hash-кода.

Таким образом, в Java8 способ вычисления памяти для строк остается таким же, но вы должны вычесть 8 байт меньше из-за отсутствия offset и length .

Если вы посмотрите на источники Oracle Java 8, у вас есть:

Значение char value[] и int hash . char имеет 2 байта, а int – 4 байта.

Так ответ не будет yourstring.length * 2 + 4?

Нет. У каждого предмета были накладные расходы. Например, массив хранит свои размеры. И как массив (объект), так и строка будут нести дополнительную память из сборщика мусора, хранящего информацию о них.

Нет надежного способа вычислить это, потому что AFAIK каждый JRE и JDK не несет ответственности за размер накладных расходов на объект.

«Alexandru Tanasescu» использует 104 байта. Вот как получить размер

  long m0 = Runtime.getRuntime().freeMemory(); String s = new String("Alexandru Tanasescu"); long m1 = Runtime.getRuntime().freeMemory(); System.out.println(m0 - m1); 

Примечание: запустите его с помощью опции -XX: -UseTLAB

Согласно следующему JEP: http://openjdk.java.net/jeps/254

Текущая реализация classа String хранит символы в массиве char, используя два байта (шестнадцать бит) для каждого символа.

В Java SE 9 это может измениться.

Обратите внимание, однако, поскольку это JEP не JSR (и он упоминает реализацию), я понимаю, что это реализация, специфичная и не определяемая JLS.

  • Начальная емкость ArrayList и IndexOutOfBoundsException
  • Как обрезать пробелы из переменной Bash?
  • Как использовать строку C ++ в структуре, когда malloc () - с той же структурой?
  • Каков наилучший способ проверить, является ли String целое число на Java?
  • Есть ли способ создать экземпляр classа по имени в Java?
  • Почему char предпочитает использовать String для паролей?
  • Заменить подстроку NSAttributedString на другую NSAttributedString
  • Разница между строкой и StringBuilder в c #
  • Найти общий префикс строк
  • Java String не работает
  • Удобное объявление строк времени компиляции в C ++
  • Давайте будем гением компьютера.