Java字符串对象及其字面量是否会被垃圾回收?
问题相关代码
// 我特意使用该构造方法 String text = new String("hello");
你对这段代码创建两个对象的判断是正确的:
- 类加载阶段,字面量
"hello"会在字符串常量池中创建对应的字符串实例 new String()执行时会在堆内存中创建另一个独立的字符串实例,内部存储字符的数组会复用常量池实例的对应数组
问题1:text指向的堆实例能否被垃圾回收?
可以。当text超出作用域、没有任何强引用指向这个堆上的new String()实例时,它会和普通堆对象一样被正常垃圾回收。
问题2:字符串常量池中的字面量对象无引用时能否被垃圾回收?
分JDK版本有不同的表现,不存在「绝对不能回收」的情况:
JDK6及更早版本
字符串常量池存储在永久代(PermGen)区域,永久代的回收条件非常苛刻:默认只有Full GC才会扫描永久代的废弃常量,未开启-XX:+PermGenGC参数时甚至不会触发永久代的回收。所以这个版本下常量池的字符串对象很难被回收,是永久代OOM的常见诱因之一。JDK7及后续版本(包括JDK8+用元空间替换永久代之后)
字符串常量池被迁移到普通堆内存区域,常量池的字符串对象和普通堆对象的回收规则基本对齐:只要没有任何强引用指向该常量池实例,就可以被GC回收,YGC和FullGC都会扫描处理。
需要注意的是:字面量生成的常量池字符串,会被定义它的类的运行时常量池持有引用,只有当这个类被卸载、且没有其他任何地方引用该字符串时,它才会满足回收条件。
内容的提问来源于stack exchange,提问作者vishal joshi
相关产品推荐
相关产品推荐

