Класс java.lang.String пожалуй один из более всего используемых в Java. С помощью строк можно хранить большое множество разных типов данных. Далее в статье мы подробнее рассмотрим, как JVM хранит данные, оптимизацию хранения и другие особенности строк в Java.
Что такое pool строк
Это определенное хранилище в памяти JVM для хранение строк. Еще это хранилище называется, как Java String Pool. В зависимости от версии Java хранится данные будут по разному.
В Java 6 строки хранились в PermGen пространстве, которое настраивалось при старте JVM. Данное пространство памяти было статическим, расширять его в run time не было возможности, а при переполнении памяти возникала ошибка OutOfMemory.
Больше информации о Permanent Generation разделе памяти можно получить тут.
После Java 7 строки хранятся в Heap пространстве, где переодически происходит очистка памяти при помощи Garbage Collector. Все строки на которые нет ссылок будут удалены и, соотвественно, память будет освобождена.
Преимущество хранение строк в String Pool в том, что так как сама по себе строка это immutable массив символов, в памяти физически хранится только один экземпляр данных. Это в свою очередь позволяет сравнивать строки по адресу в памяти, примерно так:
String first = "Netifty";
String second = "Netifty";
System.out.println(first == second); // True
Создание нового объекта строки с помощью конструктора new String
В Java существует два типа строк, первый это строковые литералы(строки, которые созданы без конструктора) и второй тип это строковые объекты(строки, которые созданы при помощи:
new String("new string"));
Помимо разницы в создании строк существует еще и разница хранения объектов в памяти. Литералы хранятся в String Pool контейнере памяти, а строки объекты в Heap.
На, что влияет разница хранения строковых данных? Пожалуй на объемы хранимых данных. Если у нас есть множество не уникальных данных, более рационально их хранить в строковых литералах.
Также при сравнении одинаковых строк по адресу памяти в будет получать отрицательный результат:
String first = "Netifty";
String second = "Netifty";
System.out.println(first == second); // True
String firstNew = new String("Netifty");
System.out.println(first == firstNew); // False
Упаковка строк в String Pool
Даже если у нас есть множество одинаковых строковых объектов мы можем их поместить в String Pool. В таком случаее мы достигнем существенной экономии памяти. Специально для этих целей в Java существует метод intern.
Пример кода, помещающего строки в String Pool:
String first = "Netifty";
String firstNew = new String("Netifty");
System.out.println(first == firstNew); // False
firstNew = firstNew.intern();
System.out.println(first == firstNew); // True
Оптимизация
В Java 6 единственной опцией оптимизации могло быть увеличение Permanent Generation пространства памяти с помощью параметра:
-XX:MaxPermSize=1G
После Java 7 у вас есть возможность управлять пространством строк с помощью параметра:
-XX:StringTableSize=4901
Также для диагностики могут применяться следующие флаги:
-XX:+PrintFlagsFinal
-XX:+PrintStringTableStatistics
Заключение
В этой статье мы рассмотрели основы хранение строк в JVM. Следуя этим рекомендациями можно существенно повысить производительность и экономию памяти ваших приложений.