字符串文本的垃圾回收

2022-09-02 04:00:29

我正在阅读有关垃圾回收的信息,当我搜索String文字垃圾回收时,我得到了令人困惑的搜索结果。

我需要澄清以下几点:

  1. 如果一个字符串在编译时被定义为文本[例如:]那么它会被垃圾回收吗?String str = "java"

  2. 如果使用实习生方法[例如:],那么它会被垃圾收集吗?此外,它将与第 1 点中的字符串文字区别对待。String str = new String("java").intern()

  3. 有些地方提到,只有在卸载类时,文本才会被垃圾回收?这有意义吗,因为我不认为类会被卸载。StringString


答案 1

如果一个字符串在编译时被定义为文本[例如:]那么它会被垃圾回收吗?String str = "java";

可能不是。代码对象将包含对表示文本的对象的一个或多个引用。因此,只要代码对象是可访问的,对象就会是。StringString

代码对象可能会变得无法访问,但前提是它们是动态加载的...并且它们的类装入器被销毁。

如果我使用实习生方法[例如:],那么它会被垃圾收集吗?String str = new String("java").intern()

调用返回的对象将是表示字符串文本的同一对象。(文本在类加载时被暂存。然后,当您在代码段中将新构造的对象实习时,它将查找并返回先前的暂存字符串。intern"java""java"String"java"

但是,与字符串文本不相同的插入字符串在变得不可访问时可能会被垃圾回收。PermGen空间在所有最近的HotSpot JVM上都被垃圾回收(在Java 8之前...这完全放弃了PermGen。

此外,它将与第 1 点中的字符串文字区别对待。

不。。。因为它与字符串文本是同一对象。

事实上,一旦你理解了发生了什么,很明显字符串文本也不会被特殊对待。它只是“可访问性”规则的应用...

有些地方提到,只有在卸载类时,文本才会被垃圾回收?这有意义吗,因为我不认为这个类会被卸载。StringString

你是对的。这是没有道理的。说这一点的消息来源是不正确的。(如果您发布一个URL,以便我们可以自己阅读他们所说的内容,那将很有帮助......


答案 2

在正常情况下,字符串文本和类都分配到 JVM 的永久生成(“PermGen”)中,通常不会被收集。被暂存的字符串(例如)存储在permgen中该类拥有的内存池中,并且曾经有一种情况是,主动性滞留可能导致空间泄漏,因为字符串池本身包含对每个字符串的引用,即使不存在其他引用。显然,至少在JDK 1.6之前,这已经不再是真的了(例如,参见这里)。mystring.intern()String

有关permgen的更多信息,这是对该主题的一个不错的概述。(注意:该链接指向与产品关联的博客。我与博客,公司或产品没有任何关联,但博客条目很有用,与产品没有太大关系。