Подтвердить что ты не робот

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

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

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

Спасибо!

4b9b3361

Ответ 1

Java7 или ниже

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

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

So

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

Общие сведения об использовании памяти строк ( ИСТОЧНИК)

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

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

Это означает, что даже если строка не содержит символов, для массива 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

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

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

Ответ 2

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

A char value[] и a int hash. A char - 2 байта, а int - 4 байта.

Таким образом, ответ не будет yourstring.length * 2 + 4?

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

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

Ответ 3

"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

Ответ 4

В соответствии со следующим JEP: http://openjdk.java.net/jeps/254

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

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

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