Как Java внедрит шаблон излучения для строки под капотом?

StackOverflow https://stackoverflow.com/questions/2909848

Вопрос

Если у вас есть два экземпляра строки, и они равны, в Java они будут делиться той же памятью. Как это реализовано под капотом?

Редактировать: Мое приложение использует большое количество строковых объектов, многие из которых идентичны. Какой лучший способ использовать Java String Constant Pool, чтобы избежать создания пользовательской реализации лишнего веса?

Это было полезно?

Решение

Посмотрите на исходный код java.lang.String (Источник для всей Java API является частью JDK).

Подводя итоги: строка обертывает подпоследовательность char[]. Отказ Что опирается char[] никогда не изменяется. Это достигается ни один из утечек, ни захвата этого char[] вне String сорт. Однако несколько Strings может поделиться тем же char[] (см. реализацию String.substring).

Существует также механизм взаимопонимания, как объясняется в других ответах.

Другие советы

Если у вас есть два экземпляра строки, и они равны, в Java они поделится одной и той же памятью

Это на самом деле не на 100% верно.

Этот блог пост - приличное объяснение почему это так, а что Строковый постоянный пул является.

Струнные литералы интернированы в Java, поэтому на самом деле есть только один строковый объект с несколькими ссылками (когда они равны, что не всегда в этом случае). Смотрите статью java.net Все о стажере () Больше подробностей.

Также есть хороший пример / объяснение в разделе 3.10.5 строковые литералы JLS, которые говорят о том, когда строки интернированы, и когда они будут отличаться.

Это не нужно правда. Пример:

String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true

но:

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2); // false

Теперь вторая форма обескуражена. Некоторые (включая меня) думают, что String даже не должно иметь общественный конструктор. Лучшая версия вышеперечисленного будет:

String s1 = new String("hello").intern();
String s2 = new String("hello").intern();
System.out.println(s1 == s2); // true

Очевидно, вам не нужно делать это для постоянной String. Отказ Это иллюстративный.

Важный момент об этом в том, что если вы пройдете String или получить один из функции, которую вы не можете положиться на String существование канонический. Отказ А. канонический Object удовлетворяет этому равенству:

a.equals(b) == b.equals(a) == (a == b)

для неnull экземпляры a, b, данного Class.

Ответить на ваш отредактированный вопрос, у Sun JVMS у -XX:+StringCache Вариант, который в моем наблюдении может значительно снизить след памяти в тяжелой приложении строки.

В противном случае у вас есть возможность вмешиваться в ваши строки, но я был бы о том, что был бы осторожен. Строки, которые очень велики, и больше не ссылаются, все равно будут использовать память для жизни JVM.

Редактировать (в ответ на комментарий): я впервые узнал о варианте StringCache из здесь:

-Xx: + StringCache позволяет кэшировать широко распределенные строки.

Том Хотин описывает какой-то тип кэширования для улучшения некоторых ориентиров. Мое наблюдение Когда я положил его по идее, заключался в том, что след памяти (после полной сборки мусора) перешел вниз, не имея его. Это не документированный параметр, и может действительно просто оптимизировать для некоторых ориентиров. Мое наблюдение состоит в том, что это помогло, но я бы не создал важной систему на основе этого.

Две вещи, чтобы быть осторожны:

  1. Не используйте new String("abc") Конструктор, просто используйте буквальный "abc".
  2. Учитесь использовать Стажер () Метод в строковом классе. Особенно при объединении строк вместе или при преобразовании массива CHAR / BYTE MARY / ETC в строку.

intern() Возвращает всегда строки, которые объединены.

Если ваши идентичные строки поступают из фиксированного набора возможных значений, то безопасное перечисление типа - это то, что вы хотите здесь. Он не только уменьшит ваш счет строки, но это сделает для более твердого приложения. Все ваше приложение знает, что эта строка имеет семантику, прилагаемую к нему, возможно, даже некоторые удобные методы.

Мои любимые оптимизации всегда те, которые могут быть защищены, как сделать код лучше, а не быстрее. И 9 раз из 10, заменив строку с бетонным типом, приводит к более правильному и самодоступному коду.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top