深入理解 Java String#intern() 内存模型
2023-03-09 22:19:42 时间
字符串常量池是一个固定大小的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() 内存模型](http://s7.51cto.com/wyfs02/M01/5B/B5/wKiom1UQ9h2xYV10AABte_Lg64k819.jpg)
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对象对内存的占用。
相关文章
- .org域名续费多少钱
- .news域名终端案例分享(二)
- 挨踢部落直播课堂第六期:精益化数据分析—如何让你的企业具有BAT一样的分析能力
- 教你几个解决方案:轻松应对电脑蓝屏
- oeasy教您玩转vim – 5 – # 插入模式
- 性能最高提升 1400%,树莓派 32 位/64 位系统对比测试
- node: JavaScript head out of memory 内存不足导致项目运行不起来
- Chrome 将使用新的工具栏下载按钮代替底部下载栏
- .org域名费每年多少
- 树莓派获得网络安装系统功能,无需借助其他设备
- 自建Kubernetes集群接入ACK注册集群后的ECS节点初始化配置
- NanoPi M1 Plus 移植 Openharmony 之建立自己的开发仓库
- 在 Gnome 中如何共享电脑屏幕
- org域名能实名认证吗
- 【FFH】Linux下配置小熊派-鸿蒙·叔设备开发(南向)的开发环境
- 50 亿观众的 “云上奥运”,顶级媒体背后的数智化力量
- 这五年的 6 个编程感悟!
- 使用树莓派安装OpenWrt
- 一文带你玩转 CODE CHINA 的开源广场|Code China
- Linux内存管理神器:smem工具