深入领略 Java String#intern() 内存模子 架构&设计

来源:互联网 / 作者:SKY / 2016-08-18 23:14 / 点击:
各人知道,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 String#intern() 内存模子


Java 7

下面,我们切换到Jdk1.7.0_67重跑该措施,可以看到Perm区内存分派曲线很滑腻,没有呈现内存分派的征象。

深入领略 Java String#intern() 内存模子

但在Heap空间,新的工具不绝发生,时代站长网,然后不绝触发GC

深入领略 Java String#intern() 内存模子

结论

因为Perm区巨细是有限的,凡是只有几十MB,以是不保举在Java6下普及行使String.intern(),这篇文章string-intern-in-java-6-7-8的机能测试表白,在Java6底下大量行使intern()会导致应用机能的明显降落,尚有也许发生OOM错误。但从Java7开始,字符串常量池被移到了Heap空间,Heap空间的巨细只受制于呆板的真实内存巨细,因此,在Java7下行使String.intern()能更有用地镌汰一再String工具对内存的占用。

阅读延展

1
3