当前位置: 首页 > 科技观察

深入理解JavaString#intern()内存模型

时间:2023-03-17 17:20:37 科技观察

string常量池是一个固定大小的HashMap。默认桶数为1009,从Java7u40开始,默认值增加到60013。Java6中,字符串常量池放在Perm空间。从Java7开始,字符串常量池被移到Heap空间。下面我们通过测试程序窥探字符串常量池在Java6和Java7两个不同版本下的内存分配情况。测试程序.testStringPoolWithLongString();}}测试程序非常简单,一个无限循环,其中通过递增变量i来创建唯一字符串,然后使用main函数启动程序。对于Java6,我们使用Jdk1.6.0_29版本运行程序,打开JavaVisualVM监控,可以看到Perm区域不断发生GC。由此我们得出结论,虽然字符串常量池是放在Perm空间中的,但是当Perm空间接近满时,JVM会回收字符串常量池中无用的字符串。Java7下,我们切换到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对象对内存的影响。占据。