String常量池

来源:互联网 发布:caffe coffee 编辑:程序博客网 时间:2024/06/08 11:30

常量池:在java用于保存在编译期已确定的,已编译的class文件中的一份数据。它包括了关于类,方法,接口等中的常量,也包括字符串常量.

代码清单1-1

String s0=”kvill”;  String s1=”kvill”;  String s2=”kv” + “ill”;  System.out.println( s0==s1 );  System.out.println( s0==s2 ); 

代码清单1-1中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。所以我们得出s0==s1==s2; 用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

代码清单1-2

public class StringPoolTest {      public static void main(String[] args) {          String str = "abc";          char[] array = {'a', 'b', 'c'};          String str2 = new String(array);          //使用intern()将str2字符串内容放入常量池          str2 = str2.intern();          //这个比较用来说明字符串字面常量和我们使用intern处理后的字符串是在同一个地方          System.out.println(str == str2);          //那好,下面我们就拼命的intern吧          ArrayList<String> list = new ArrayList<String>();          for (int i = 0; i < 10000000; i++) {              String temp = String.valueOf(i).intern();              list.add(temp);          }          System.out.println(list.size());    }  }
代码清单1-2在JDK7下的运行结果

trueException in thread "main" java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOf(Unknown Source)at java.util.Arrays.copyOf(Unknown Source)at java.util.ArrayList.grow(Unknown Source)at java.util.ArrayList.ensureExplicitCapacity(Unknown Source)at java.util.ArrayList.ensureCapacityInternal(Unknown Source)at java.util.ArrayList.add(Unknown Source)at cn.com.test.p201612.StringPoolTest.main(StringPoolTest.java:19)

代码清单1-2在JDK6下的运行结果

trueException in thread "main" java.lang.OutOfMemoryError: PermGen spaceat java.lang.String.intern(Native Method)at cn.com.test.p201612.StringPoolTest.main(StringPoolTest.java:18)



原因是Jdk6版本中常量也是放在Perm区中的,在 jdk7 的版本中,字符串常量池已经从Perm区移到正常的Java Heap区域了。为什么要移动,Perm 区域太小是一个主要原因,当然据消息称jdk8已经直接取消了Perm区域,而新建立了一个元区域。


结合代码及图来看一下:

public static void main(String[] args) {    String s = new String("1");    String s2 = "1";    s.intern();    System.out.println(s == s2);     String s3 = new String("1") + new String("1");    String s4 = "11";    s3.intern();    System.out.println(s3 == s4);}

jdk6中的解释:



jdk7中的解释






参考资料:

http://www.cnblogs.com/wxgblogs/p/5635099.html











0 0
原创粉丝点击