2015-12-23 2 views
3

Раньше я знал, что оба следующих оператора создают строка a в постоянном бассейне во время выполнения:"a" vs 'new String ("a")' vs 'new String ("a"). Intern()' в String Constant Pool (JDK 6)

String s = "a" 
String s = new String("a") 

при тестировании их на JVM, PermGen размер одинаков для обоих случаев.


следующие фрагменты кода, однако, ведут себя по-разному от этого:

String s2 = null; 
for (int i = 0; i < 100; i++) 
{ 
    s2 = s2 + i; 
} 

Использование .intern(), размер PermGen увеличивается на каждой итерации:

String s2 = null; 
for (int i = 0; i < 100; i++) 
{ 
    s2 = s2 + i; 
    s2.intern(); 
} 

Почему это поведение наблюдаемое? s2.intern() добавить записи в пул? Чем это отличается от этих заявлений?

String s = "a" 
String s = new String("a") 
+0

'intern()' добавляет к пулу строковых литералов, поскольку это единственная цель, как задокументировано. Я не понимаю, что такое путаница. –

+0

Я использую jvisualVM, чтобы проверить..Используя .intern(), размер перменца увеличивается на каждой итерации. Другие не были ..why ??? – superman

+0

Объекты помещаются в кучу по умолчанию, для чего они предназначены. Неудивительно, что Strings являются объектами, и когда они выделены, они помещаются в кучу. Однако, когда вы 'intern()' string, вы помещаете его в пул литералов String, который находится в perm gen. –

ответ

4

Вот небольшое объяснение:

  • "a" создать строку «а» в стажера бассейне, если уже не присутствует
  • new String("a") потому, что параметр «а», строка " a « создан в пуле (если еще нет), а копия « a » создана из стажа пула
  • , взятый любой строкой s s.intern() возвращает старую копию этой строки, если она присутствует в основном пуле. Если не добавить эту строку в внутренний пул и вернуть новую копию.

Ссылка для intern() метода:

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

Примечание: создать String и не добавить его в стажера бассейн вы можете использовать массив символов в качестве параметра конструктора String:

char[] helloArray = { 'h', 'e', 'l', 'l', 'o', '.' }; 
String helloString = new String(helloArray); 

Вот ссылка на jls, где поясняется, что строковый литерал присутствует в основном пуле строк:

Строковый литерал является ссылкой на экземпляр класса String (§ 4.3.3, § 4.3.3).

Кроме того, строковый литерал всегда относится к тому же экземпляру класса String. Это потому, что строковых литералов - или, в более общем плане, строки , которые являются значениями константных выражений (§15.28) - являются «интернированных» так, чтобы разделить уникальные экземпляры, используя метод String.intern.


Здесь шаг за шагом объяснение до последнего комментария:

// Creates the string "123", add it to the intern pool and assign "123" to s 
String s = "123"; 

// s.intern() returns the intern string of s. Because s is already the 
// string "123" present in the intern pool s and s.intern() are the same 
System.out.println(s == s.intern());// true 

// "123" is already in intern pool. new String("123") create a new String 
// that equals "123" but it is a different object 
String s2 = new String("123"); 

// It prints false because s2 is equals to "123", but not the same object 
// because a new String was created in the preciding row 
System.out.println(s2 == s);// false 

// It prints true because s2.intern() returns the string present in the 
// intern pool that is equals to s2. That string exists and is "123" 
System.out.println(s2.intern() == s); // true 

Дополнительное примечание: для каждой строки с, которая равна s2, s.intern() == s2.intern() также, если s == s2 возвращает false.

// If s equals s2 but are not the same 
if (s.equals(s2) && s != s2) { 
    // THe intern string of s and s2 are always the same 
    System.out.println(s.intern() == s2.intern()); // prints always true 
} 
+0

Я использую jvisualVM, чтобы проверить..Используя .intern(), размер перггенов увеличивается на каждой итерации. Другие не были ..why ??? – superman

+0

U означает, что все они создают «a» в бассейне с ограниченными возможностями? @ Davide – superman

+0

Да, потому что вы создали буквальный «a» –

0

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