字符串文字和永久生成内存区域

时间:2012-11-14 11:21:12

标签: java string

当我们说实习字符串存储在永久生成区域中时,同样适用于字符串文字吗?或者它仅适用于由inter()实现的字符串?

实际上博客文章通常说字符串池包含对字符串对象的引用,而实际的字符串对象是在堆中的某个地方。还有很多混乱,永久世代是IN堆还是外堆。 (我使用jcosole它显示永久性不同于heap.many帖子说它作为堆的一部分,许多人说它是不同的)

修改 当我跑的时候:

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

3 个答案:

答案 0 :(得分:6)

  

当我们说实习字符串存储在永久生成区域中时,同样适用于字符串文字吗?

文字字符串被实习。所以是的,在Java 6中。 -

从Java 7开始,实习字符串不再存储在永久代中。它们存储在堆的主要部分中,就像您要创建的任何其他对象一样。

  

不应该是Java.lang.OutOfMemoryError:PermGen space

您获得的异常是由创建堆上的数组引起的。要尝试获取“out of permgen memory”错误,您可以尝试删除list.add()行。但请注意,实习字符串可以被垃圾收集,因此即使这样做也不会导致您期望的异常。

Cf RFE 6962931

  

在JDK 7中,实例化的字符串不再分配在Java堆的永久生成中,而是分配在Java堆的主要部分(称为年轻和旧的代),以及创建的其他对象通过申请。此更改将导致更多数据驻留在主Java堆中,并且永久生成中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序只会看到堆使用中的相对较小的差异,但是加载许多类或大量使用String.intern()方法的较大应用程序将看到更显着的差异。

答案 1 :(得分:2)

所有字符串文字都会自动实现,如String JavaDoc

中所述
  

所有文字字符串和字符串值常量表达式都是实体。

我希望手动实习的字符串和任何字符串文字之间的行为一致。

答案 2 :(得分:0)

s.intern()返回对实习字符串的引用,但您没有使用它。 试试s = s.intern()