【问题标题】:Are interned strings eligible for garbage collection in Java 8?在 Java 8 中,interned 字符串是否有资格进行垃圾回收?
【发布时间】:2017-04-06 20:09:30
【问题描述】:

我在 Daniel Liang 关于 Java 编程的最新著作(第 386 页,第 10 版)中看到了以下文字:

下面的代码会改变字符串的内容吗?

String s = "Java";

s = "HTML";

答案是否定的。 .... 赋值后第一个String对象仍然存在,但是不能再访问了,因为变量s现在指向了新的对象,如图10.15所示。

根据上面的文字,作者的观点似乎是字符串对象“Java”没有被垃圾回收,即使它不再被引用。我知道 Java 中实习字符串的存储位置发生了一些变化。请记住,上面的书是关于 Java SE 8 的。

但根据 Java 垃圾收集器,未使用的对象(不再引用的对象)会自动被垃圾收集。

那么哪种情况是 Java SE 8 的实际情况?

【问题讨论】:

  • 我不认为作者声称字符串不能被 GC'ed;该陈述在非正式意义上是正确的,人们可能会看到它也适用于其他(非字符串)类型。
  • 作为一个整体,在其代码中,仍然带有对该字符串字面量的引用。

标签: java string garbage-collection


【解决方案1】:

字符串文字是实习字符串,但并非所有实习字符串都是字符串文字。

字符串文字由定义它们的类保持活动状态,而这些类又由实例和类加载器保持活动状态。您需要卸载类才能使它们符合 GC 的条件。

另一方面,内部字符串只能保证如果string1.equals(string2) 那么string1.intern() == string2.intern()。这个特定的定义允许对实习字符串进行垃圾收集,因为oldInternedString != newInternedString 是不可观察的,因为如果它已被垃圾收集,则无法引用oldInternedString。所以字符串实习表可以被(但不是必需的)实现为弱引用表,这允许它们被GCed。

【讨论】:

    【解决方案2】:

    作者的观点实际上与垃圾收集没有太大关系。对象将在将来的某个时间被垃圾回收这一事实与在分配后它仍然存在的断言并不矛盾。他并不是说它会永远存在,只是说赋值不会改变原始对象。

    【讨论】:

    • 但是他已经在前面的第 7 章中针对数组和第 9 章针对一般对象介绍了垃圾收集。因此,当我在第 10 章读到上述字符串的上下文时,我听上去很困惑。不管那本书里的文字如何,你能回答我的问题吗?
    • 我认为你是对的,对象将被垃圾收集。我只是不同意您的断言,即作者的观点是字符串对象“Java”不是垃圾收集的。他声明对象没有被新赋值改变的事实并不意味着它不会在某个时候被垃圾收集。
    • 感谢您的澄清。
    • 我的荣幸。我当然可以看出这会使书中的写作方式感到困惑。
    猜你喜欢
    • 2018-07-19
    • 2013-05-13
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多