Как хранится в памяти java.lang.String. Оптимизация использования.

Класс 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. Следуя этим рекомендациями можно существенно повысить производительность и экономию памяти ваших приложений.

Related posts

Leave a Comment