Постоянный бассейн струны в Java
В Java есть две формы создания объекта строкового объекта. Один из них - буквальная форма, такая как String str = "droid"; а другой является стандартным методом построения объектов с использованием новых, таких как String Str = New String ("droid");. Мы часто используем эти два метода при написании кода, особенно буквального метода. Тем не менее, эти две реализации действительно имеют некоторые различия в производительности и использовании памяти. Все это связано с тем, что JVM сохраняет специальную память, чтобы уменьшить повторное создание строковых объектов, которые представляют собой пул строки или буквальный пул.
Как это работает
Когда в коде создается строковый объект в литеральной форме, JVM сначала проверит буквальный. Если есть ссылка на строковый объект с тем же контентом в пуле String Constrate, ссылка будет возвращена. В противном случае будет создан новый объект String, а затем ссылка будет помещена в пул строковых постоянных, а ссылка будет возвращена.
Привести пример
Буквальная форма создания
String str1 = "droid";
JVM обнаруживает этот буквальный, здесь мы думаем, что нет объекта с содержанием не существует. JVM не может найти объект String с содержимым Droid через пул String Constant, поэтому он создаст этот объект строки, а затем поместит ссылку на объект, который вы только что создали в пул строки постоянных, и вернет ссылку на переменную STR1.
Если есть такой код, как этот
String str2 = "droid";
Точно так же JVM все еще должен обнаружить этот буквальный. Поиск пула String Constant, JVM обнаружил, что существует содержимое строкового объекта «Droid», поэтому он возвращает ссылку на существующий объект строки в переменную STR2. Обратите внимание, что новые строковые объекты не будут воссозданы здесь.
Убедитесь, указывают ли Str1 и Str2 на один и тот же объект, мы можем использовать этот код
System.out.println (str1 == str2);
Результат верен.
Создать с новым
String str3 = new String ("droid");
Когда мы используем новые для построения строковых объектов, будут созданы новые строковые объекты независимо от того, есть ли ссылки на объекты с одним и тем же содержимым в пуле String Constrate. Итак, давайте используем следующий код для его проверки.
String str3 = new String ("droid");
System.out.println (str1 == str3);
Результат является ложным, как мы думаем, указывая на то, что две переменные указывают на разные объекты.
стажер
Для объекта String, созданного с новым выше, если вы хотите добавить ссылку в Pourse String Pourse, вы можете использовать метод стажировки.
После звонков в интернет сначала проверьте, есть ли ссылка на объект в пуле Strong Constrate. Если он существует, верните эту ссылку на переменную, в противном случае ссылка будет добавлена и возвращена в переменную.
String str4 = str3.intern ();
System.out.println (str4 == str1);
Результат вывода верно.
Сложные проблемы
Предварительные условия?
Предварительным условием для реализации постоянных пулов строк является то, что строковые объекты в Java неизменны, что может безопасно гарантировать, что несколько переменных имеют один и тот же объект. Если объект String в Java является переменным, а одна ссылка изменяет значение объекта, также будут затронуты другие переменные, очевидно, что это необоснованно.
Ссылка или объект
Этот вопрос наиболее распространен, когда пул строкости сохраняется в ссылке или объекте. Строковая постоянная пул хранит ссылки на объекты, а не объекты. В Java объекты создаются в памяти кучи.
Проверка обновления, многие полученные комментарии также обсуждают эту проблему, и я просто проверяю его. Проверьте окружающую среду
22: 18: 54-androidyue ~/videos $ cat/etc/os-releaseName = fedoraversion = "17 (мясное чудо)" id = fedoraversion_id = 17petty_name = "Fedora 17 (мясной Miracle) "ansi_color =" 0; 34 "CPE_NAME =" CPE:/O: FedorAproject: Fedora: 17 "22: 19: 04-Androidyue ~/Видео $ java -versionjava версия" 1.7.0_25 ". (Build 23,7-B01, смешанный режим)
Идея проверки: следующая программа Java считывает видеофайл размером 82 м и выполняет операции по стажерам в форме строки.
22: 01: 17 -androidyue ~/Видео $ ll -lh | grep Why_to_learn.mp4-rw-rw-r--. 1 Androidyue Androidyue 82 м 20 октября 2013 г. Why_to_learn.mp4
Проверочный код
Импорт java.io.bufferedReader; Import java.io.filenotFoundException; импорт java.io.filereader; import java.io.ioexception; открытый класс Testmain {Private Static String fileContent; public static void main (string [] args) {filecontent = readfileToString (args [0]); if (null! = filecontent) {filecontent = filecontent.intern (); System.out.println ("не null"); }} частная статическая строка readfileToString (string file) {BufferedReader Reader = null; try {reader = new BufferedReader (new FileReader (файл)); StringBuffer buff = new StringBuffer (); Строка; while ((line = reader.readline ())! = null) {buff.append (line); } return buff.toString (); } catch (filenotFoundException e) {e.printstackTrace (); } catch (ioException e) {e.printstackTrace (); } наконец {if (null! = Reader) {try {reader.close (); } catch (ioException e) {e.printstackTrace (); }}} return null; }}Поскольку пул строки постоянно существует в постоянной генерации в памяти кучи, он подходит перед Java 8. Мы проверяем, установив постоянную генерацию небольшого значения. Если объект String существует в пуле String Constrate, должна быть выброшена ошибка пространства пермимента java.lang.outofmemororror pertgen.
java -xx: permsize = 6m testmain ~/videos/phys_to_learn.mp4
Запуск Proof Program не бросает OOM, но это не может доказать, что она хранится как объект или ссылка.
Но это, по крайней мере, доказывает, что фактический объект контента char [] строки не хранится в пуле String Constant. В этом случае это не так важно, чтобы пул строки сохраняет ссылки на строки объектов или строковые объекты. Но люди все еще склонны хранить ссылки.
Плюсы и минусы
Преимущество постоянного пула строки состоит в том, чтобы уменьшить создание строк того же контента и сохранить пространство памяти.
Если вы должны сказать недостатки, это то, чтобы пожертвовать процессором вычисления времени для обмена пространством. Время расчета процессора используется в основном для обнаружения, существуют ли ссылки на объекты с тем же контентом в пуле строковых постоянных. Тем не менее, его внутренняя реализация является хэштибельной, поэтому стоимость расчета низкая.
GC Recycling?
Поскольку пул строки постоянно содержит ссылку на объект общего строки, означает ли это, что эти объекты не могут быть переработаны?
Прежде всего, общие объекты в вопросе, как правило, меньше. Насколько я подтвердил, в более ранних версиях действительно была такая проблема, но с введением слабых ссылок эта проблема должна исчезнуть в настоящее время.
Что касается этой проблемы, вы можете узнать больше об этой статье. Интернизованные струны: java glossary
Использовать стажер?
Предварительным условием для использования стажировки является то, что вы знаете, что вам действительно нужно его использовать. Например, у нас здесь есть запись миллионов, где определенная ценность записи - Калифорния, США много раз. Мы не хотим создавать миллионы таких строковых объектов. Мы можем использовать Intern, чтобы сохранить только одну копию в памяти. Для более глубокого понимания стажера, пожалуйста, обратитесь к углубленному анализу String#near.
Всегда есть исключения?
Знаете ли вы, что следующий код создаст несколько строковых объектов и сохранит несколько ссылок в пуле String Constrate?
String test = "a" + "b" + "c";
Ответ заключается в том, что создается только один объект, и в постоянном пуле сохраняется только одна ссылка. Мы используем декомпиляцию Javap и смотрим на это.
17:02. Код: 0: ALOAD_0 1: INLOKPECIAL #1; // Метод java/lang/object. "<int>" :() V 4: returnpublic static void main (java.lang.string []) Throws java.lang.exception; Код: 0: LDC #2; // String ABC 2: Store_1 3: возврат
Ты это видел? Фактически, в течение периода сборника эти три литерала были синтезированы в один. Это на самом деле оптимизация, которая позволяет избежать создания избыточных строковых объектов и не имеет проблем с строчками. Для строки строки вы можете просмотреть подробности Java: строки строки.
Выше приведено сборник информации о постоянных пулах строки в Java. Мы будем продолжать добавлять соответствующую информацию в будущем. Спасибо за поддержку этого сайта!