Длинные статические строки в короткоживущих объектах
Это может быть глупый вопрос (или просто заставляйте меня выглядеть глупо:)), однако мне было бы интересно, как работать с длинными объектами 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