JVM15_new String、StringTable的垃圾回收行为、G1的String去重操作

本文详细探讨了Java中字符串对象的创建过程,包括`newString()`与`intern()`方法的使用。讲解了在JDK6、7、8中不同版本下,`intern()`方法的行为差异及其对内存的影响。分析了字符串常量池在不同JDK版本中的位置变化,以及如何通过`intern()`优化内存使用。同时,讨论了垃圾回收机制在字符串对象管理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

new String(“ab”)到底创建了几个对象

在这里插入图片描述
从字节码的角度可以很清楚的知道是两个对象。
第一个就是new关键字创建了一个String对象在堆中,第二个,这个ab字符串对象第一次出现,所以会在堆中的字符串常量池创建,然后从常量池取出字符串ab (ldc指令是从常量池中获取值的) , 放到堆中String对象的空间中。str 引用指向了String 对象

String s = new String(“a”) + new String(“b”);

在这里插入图片描述
通过字节码可以看到,首先因为是 加号左右是引用变量,所以创建了StringBuilder对象,接着就是两个new String()以及常量池中字符串对象的创建
最后StringBuilder的toString方法中是存在new String()操作的,
也就是总共创建 了6个对象。
在这里插入图片描述

再看toString方法,发现并没有字符串"ab", 也就是字符串常量池不存在ab

最后也就是new String(“ab”) ,然后str 指向了堆中的这个String 对象

一道面试题

在这里插入图片描述
JDK6中,字符串常量池是在永久代。
对于上边代码执行结果是false\false
首先String s = new String(“1”); 在堆中创建一个对象,并且因为常量池此时也没有这个字符串,所以也同时创建了一个
s.inter(); 这步就有点多余,常量池已经存在字符串"1" 了
String s2 = “1”; s2 指向的是字符串常量池中的1 ,而s 指向的是堆中的1,所以返回false

String s3 = new String() + new String(); 这一步相当于String s3 = new String(“11”); 由开始的案例知道,此时在常量池并不存在11
s3.intern();在常量池产生了11
s4 使用上一行产生的11, s3指向堆中11,s4指向常量池11,所以返回false

**JDK7或8 **
返回结果是:false、true
前半个代码解释一样。
String s3 = new String() + new String(); 这一步相当于String s3 = new String(“11”); 由开始的案例知道,此时在常量池并不存在11
s3.intern(); 此时这一步是关键,它并没有在常量池中创建字符串对象11, JDK7中因为字符串常量池也在堆中,为了节省空间,在常量池中只放了一个s3的引用
String s4 = “11”; 此时s4指向常量池中的引用,而这个引用指向堆中的字符串11
所以s3 和s4都指向了同一个对象,返回true

JDK6中
在这里插入图片描述
JDK7、8
在这里插入图片描述
拓展:
s3 指向堆中的11,但是并没有在字符串常量池放11
s4指向字符串常量池中新创建的字符串对象11
s3调用intern()方法,就会去字符串常量池中检查是否存在这个字符串11,发现存在这个字符串,所以就会返回常量池中这个字符串的地址
所以此时s5和s4都指向常量池中的11
在这里插入图片描述
总结
在这里插入图片描述
案例1
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

intern()空间效率测试

字符串的操作,加了intern()
首先是时间上的提升,然后再观察内存的占用,因为在前边的操作中已经在字符串常量池中创建过1-10,所以后边只是一个引用返回,节省了在堆中创建字符串对象的时间和空间
在这里插入图片描述

在这里插入图片描述
new String(“a”).intern(); 的操作,在字符串常量池中产生a字符串后,堆中的a就失去作用,在以后就会进行GC

对于程序中大量存在的字符串,尤其是其中存在很多重复字符串时,使用intern()可以节省内存空间

在这里插入图片描述

StringTable的垃圾回收行为

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
String.valueOf(j) 底层还是一个new String()
当new String().intern() ,对象创建很多以后,就会出现YGC,回收掉堆中那些没用的字符串对象

G1的String去重操作

在这里插入图片描述
在这里插入图片描述
hashtable用的很多,所以面试常考
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值