深入理解 java string#intern() 内存模型-亚博电竞手机版

大家知道,java中string.intern()方法调用会先去字符串常量池中查找相应的字符串,如果字符串不存在,就会在字符串常量池中创建该字符串然后再返回。

字符串常量池是一个固定大小的hashmap,桶的数量默认是1009, 从java7u40开始,该默认值增大到60013。在java6当中,字符串常量池是放在perm空间的,从java7开始,字符串常量池被移到heap空间。下面,我们通过测试程序来窥探字符串常量池在java6,java7两个不同版本底下的内存分配情况。

测试程序

public class stringpooltest {      public void teststringpoolwithlongstring(){         long i=0;         while(true){             string longstring = "this is a very long string, very very long string to test the gc behavior of the string constant pool" i;             longstring.intern();             i  ;         }     }      public static void main(string[] args){         stringpooltest stringpooltest = new stringpooltest();         stringpooltest.teststringpoolwithlongstring();     } }

测试程序很简单,一个死循环,循环里面通过递增变量i制造唯一的字符串,然后用main函数启动程序。

java 6

我们使用版本jdk1.6.0_29来跑该程序,打开java visualvm监控,可以看到,perm区不断发生gc,由此的出结论,虽然字符串常量池放在perm空间,但当perm空间接近满的时候,jvm会将字符串常量池中的无用字符串回收掉。

java 7

下面,我们切换到jdk1.7.0_67重跑该程序,可以看到perm区内存分配曲线很平滑,没有出现内存分配的现象。

但在heap空间,新的对象不断产生,然后不断触发gc

结论

由于perm区大小是有限的,通常只有几十mb,所以不推荐在java6下广泛使用string.intern(),这篇文章string-intern-in-java-6-7-8的性能测试表明,在java6底下大量使用intern()会导致应用性能的显著下降,还有可能产生oom错误。但从java7开始,字符串常量池被移到了heap空间,heap空间的大小只受制于机器的真实内存大小,因此,在java7下使用string.intern()能更有效地减少重复string对象对内存的占用。

展开全文
内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

最新文章

网站地图