【问题标题】:Why doesn't JVM garbage-collect unreferenced String objects immediately?为什么 JVM 不立即垃圾收集未引用的 String 对象?
【发布时间】:2014-11-25 18:15:29
【问题描述】:

所以,如果我声明一个String对象str并给它赋值,然后给同一个String对象str赋值不同的值,由于String类是不可变的,一个新的String对象会在内存中创建,str现在指向到这个新对象。但是,既然旧的 String 对象现在没有被引用,为什么不能立即进行垃圾回收呢?我知道,如果使用相同的值创建一个新的 String 文字,则会返回相同的早期对象,但无论如何它不太可能发生。当 JVM 知道糟糕的开发人员在他巨大的 for 循环的每次迭代中创建 3 个 String 对象时,它是否有理由不运行 GC?

【问题讨论】:

  • 我知道如果创建了一个新的字符串字面量如何创建和分配你的String 对象?
  • 我的意思是我做 String strAllOverAgain = "asd"; //假设 asd 是之前字符串的值
  • String foo = "asd"; foo = "asd"; 不会重新创建 asd 字符串实例。它正在重复使用相同的内容。并且引用“asd”不会创建它,它可以是存在于某处的常量,可能是因为使用它的类已加载
  • 我知道。我的意思是这个。 String foo ="asd"; System.out.println("foo is " + foo.hashCode()); foo = "def"; System.out.println("foo is " + foo.hashCode()); String boo = "asd"; System.out.println("boo is " + boo.hashCode());
  • 关于文字的创建方式/时间/地点:blog.jamesdbloom.com/JVMInternals.html#constant_pool

标签: java string garbage-collection jvm


【解决方案1】:

因为不值得花时间。在这个问题上,分代收集器比在分配时对每个字符串进行微管理要快得多。与复制收集器大量执行的操作相比,管理少量内存的开销很大。

【讨论】:

    【解决方案2】:

    注意 自 java 7 以来,以下行为已更改,以防止出现下面描述的问题。 这个答案给出了很好的详细解释Java 7 String - substring complexity

    除了威尔所说的,每次创建“字符串”并不意味着 JVM 可能没有对该字符串的其他引用。这是因为 String 的“实习生”行为

    例如

    String x = "This is a new string"
    String y = x.subString(0,1) ; //y = "T"
    x = null; //discard X
    

    但是,内部不会创建新的字符串文字。相反,“x”和“y”都引用了相同的文字字符串。 “字符串”的开始和结束索引属性 y 将是 (0,1) --> 指向文字 --> “这是一个新字符串”

    免责声明:术语可能不完全准确

    【讨论】:

    • y 不会引用x 引用的相同String(或者更确切地说是它的支持char[])。至少从 Oracle JDK 7 开始就没有了。
    • 是的,这在 java 7 中发生了变化,我不知道。将添加注释
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    相关资源
    最近更新 更多