【问题标题】:If I let a string reference escape, will this prevent the containing object to be garbage-collected?如果我让字符串引用转义,这会阻止包含对象被垃圾收集吗?
【发布时间】:2012-09-02 04:36:28
【问题描述】:

假设我有一个包含如下字符串的对象:

class SomeObject  {
   private final String s;
   private final int i;

   SomeObject(String s, int i) {
      this.s = s;
      this.i = i;
   }

   String getString() {
      return s;
   }
}

所以如果我只使用没有SomeObject 的引用,例如我用来构建另一个对象并且我不需要i 和任何其他可能的字段,它会被垃圾收集吗?

编辑:我很抱歉不清楚。假设我有一个名为 someObject 的 SomeObject 实例,如果我让 s 引用使用 getString() 方法转义,即 someObject.getString() 并使用返回的引用来构建其他对象,例如不是 SomeObject 实例,是否可以将 someObject 用于垃圾回收?

【问题讨论】:

  • 你使用什么参考?参考什么?
  • 什么会被垃圾回收?
  • 我稍微编辑了这个问题,我希望这会更好。仅供参考,我不是本地人

标签: java garbage-collection


【解决方案1】:

我猜你指的是s?是的,SomeObject 的实例将免费用于垃圾收集。 String 没有引用它所源自的 SomeObject

【讨论】:

  • 所以作为一般规则,如果一个字段不包含对包含对象的引用,那么包含对象可以被垃圾回收吧?
  • @user1364534:是的,更一般地说,如果没有对某物的引用,它可以被垃圾收集。
  • 非常感谢。我很困惑,因为内部类是内存泄漏的原因,因为它们持有对外部类的引用,从而防止它们被垃圾收集。我心想,我问的问题是否就是这种情况。顺便说一句,您知道静态内部类是否会阻止任何外部类被垃圾收集。例如,假设类 A 包含静态内部类 B 的定义。B 对象的实例化会阻止 A 的所有实例被垃圾回收吗?
  • @user1364534 不,静态内部类不会自动引用外部类的任何实例,因此不会阻止它们被垃圾收集。这就是静态内部类的全部意义所在。
【解决方案2】:

getString() 将返回s,但不会从当前SomeObject 中“删除”它。如果将值x 分配给s

s = x;

x 仅在您将新值 y 分配给 s 时才会被垃圾回收

s = y;

并且没有对 x left 的引用。

【讨论】:

    【解决方案3】:

    让我问你这个。

    final class Foo {
      String value = "initial";
    }
    

    假设你执行如下代码...

    final Foo foo = new Foo();
    final String val = foo.value;
    foo.value = "replaced";
    

    现在,您认为 val 现在会等于 "replaced" 吗?希望不会,因为它不会;看来您对参考是什么有一些误解。使用val = foo.value,您将字段foo.value 的值复制到val;该值是对"initial" 字符串的引用。它不是对字段foo.value 的引用。保持对"initial" 的引用不会阻止foo 被垃圾回收。

    【讨论】:

    • 谢谢,我知道什么是参考。我只是想知道对象和它们的领域之间的关系是否比我所知道的更深。虽然他们不这样做是很自然的,但使用像 Java 这样的高级语言,我无法确定。
    猜你喜欢
    • 2014-03-18
    • 2015-10-08
    • 1970-01-01
    • 2015-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-14
    相关资源
    最近更新 更多