Строковые литералы и область памяти постоянного поколения

Когда мы говорим, что интернированные строки хранятся в области постоянного поколения, то делает то же самое применимо и для строковых литералов? Или это только для строк, интернированных inter()?

Фактически сообщения в блоге обычно говорят, что пул строк содержит ссылку на строковый объект, а фактический строковый объект находится где-то в куче. также существует большая путаница в том, что постоянное поколение находится в куче или за его пределами. (я использовал jcosole, он показывает постоянный ген, отличный от heap.many сообщений говорят, что это часть кучи, и многие говорят, что это другое)

Edit: Также, когда я бежал:

public class stringtest2{
  public static void main(String args[]){
    int i=0;
    List<String> list=new ArrayList<String>();
    while(true){
      String s="hello"+i;
      String s1=i+"hello";
      String s2=i+"hello"+i;
      System.out.println(s);
      s.intern();

      s1.intern();
      s2.intern();
      list.add(s);
      list.add(s1);
      list.add(s2);
      i++;
    }
  }
}

Я ожидал Java.lang.OutOfMemoryError: PermGen space Но я получил:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.util.Arrays.copyOf(Arrays.java:2760)
        at java.util.Arrays.copyOf(Arrays.java:2734)
        at java.util.ArrayList.ensureCapacity(ArrayList.java:167)
        at java.util.ArrayList.add(ArrayList.java:351)
        at stringtest2.main(stringtest2.java:20)

Не должно быть Java.lang.OutOfMemoryError: PermGen space

Ответ 1

Когда мы говорим, что интернированные строки хранятся в области постоянного поколения, то делает то же самое применимо и для строковых литералов?

Литеральные строки интернированы. Так что да, в Java 6 -.

Из Java 7 интернированные строки больше не сохраняются в постоянном поколении. Они хранятся в основной части кучи, как и любые другие объекты, которые вы создали.

Не должно быть Java.lang.OutOfMemoryError: пространство PermGen

Исключение, которое вы получаете, вызвано созданием массива, который живет в куче. Чтобы попытаться получить ошибку "из памяти пермг", вы можете попытаться удалить строки list.add(). Обратите внимание, однако, что интернированные строки могут быть собраны мусором, поэтому даже это не приведет к ожидаемому исключению.

Cf RFE 6962931:

В JDK 7 интернированные строки больше не выделяются в постоянном поколении кучи Java, а вместо этого выделяются в основной части кучи Java (так называемые молодые и старые поколения) вместе с другими созданными объектами по заявке. Это изменение приведет к большему количеству данных, находящихся в основной куче Java, и меньше данных в постоянном поколении, и, следовательно, может потребоваться корректировка размеров кучи. Из-за этого изменения в большинстве приложений будут наблюдаться только относительно небольшие различия в использовании кучи, но более крупные приложения, загружающие многие классы или интенсивно использующие метод String.intern(), будут видеть более значительные различия.

Ответ 2

Все строковые литералы интернированы автоматически, как описано в String JavaDoc:

Все литералы и строковые константные выражения интернированы.

Я ожидаю, что поведение будет согласовано между строками, которые вы вручную станете, и любыми строковыми литералами.

Ответ 3

s.intern() возвращает ссылку на интернированную строку, но вы ее не используете. Попробуйте s = s.intern()