Длинные статические строки в короткоживущих объектах

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

Подумайте о длинных SQL-запросах в заданиях cron или анонимных, командных или функциональных классах. Это очень короткоживущие классы и даже будут использовать эти длинные строки один раз в жизни в течение большей части времени. Что лучше? Чтобы построить String inline и позволить ему собираться с экземпляром или сделать его неподвижным окончательным в любом случае и позволить им сидеть в памяти бесполезно до тех пор, пока классы не будут созданы после следующего экземпляра?

Ответ 1

Ну, есть только такой контроль над тем, что происходит со строкой.

Даже если вы создадите его в строке, эта строка, скорее всего, будет добавлена ​​в пул констант String JVM и будет повторно использована при повторном объявлении, поэтому на практике вы, вероятно, будете повторно использовать один и тот же объект String в любом случае.

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

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

Ответ 2

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

Создание длинных строк не статически. Для SQL используйте подготовленные операторы с владельцем места ?. То же самое относится к строкам с заполнителями: используйте MessageFormat.

Чтобы быть явным. Следующие дополнительные расходы не стоят:

static final String s = "... long string ...";

Ответ 3

Когда оставшаяся память ограничена, JVM обычно выполняет очистку пространства gen и освобождает неиспользуемые/не привязанные классы. Поэтому наличие длинных строк в качестве статической переменной на мой взгляд не наносит большого вреда

Ответ 4

Если вы чувствуете, что ваши строки могут занимать много памяти, не делайте их статическими или объявляйте их с помощью строкового литерала. Поскольку оба из них будут храниться в пространстве перггена и будут почти почти собраны мусор [есть шанс, но тонкий, статика никогда не может быть собрана мусором, вы не создали свой собственный загрузчик классов). Поэтому создайте String с помощью нового оператора, чтобы он был создан в куче и может быть легко собрано мусором i.e.

String str = new String("long string");

EDIT:

Как сохраняются строки: http://www.ntu.edu.sg/home/ehchua/programming/java/J3d_String.html

EDIT:

Ниже рассказывается о том, как работает новая строка. Аргумент представлен в том, что новая строка создаст 2 объекта один в куче и один в пуле. ЭТО НЕПРАВИЛЬНО, по умолчанию это неверно, и вы можете заставить java сделать это, вызвав метод intern. Чтобы поддержать мой аргумент, следует javadoc из класса Strin для метода intern:

стажер

public String intern() Возвращает каноническое представление для строковый объект. Сохраняется пул строк, изначально пустых. в частном порядке классом String.

При вызове метода intern, если пул уже содержит строка, равная этому объекту String, определяемая равными (Object) метод, то возвращается строка из пула. В противном случае это Объект String добавляется в пул и ссылка на эту строку объект возвращается.

Отсюда следует, что для любых двух строк s и t s.intern() == t.intern() истинно тогда и только тогда, когда истинны s.equals(t).

Все литералы и строковые константные выражения интернированы. Строковые литералы определены в §3.10.5 языка Java Спецификация

Как видно из предыдущего документа, если новая строка всегда создавала объект в пуле, то метод intern будет абсолютно бесполезным!! Также логически это не имеет никакого смысла.

EDIT:

Также читайте ответ на этот пост: Пул строк, создающий два строковых объекта для одной строки в Java