【问题标题】:How many objects eligible for Garbage Collector有多少对象符合垃圾收集器的条件
【发布时间】:2012-03-07 20:37:53
【问题描述】:
class A{
     A aob;
     public static void main(String args[]){
          A a=new A();
          A b=new A();
          A c=new A();
          a.aob=b;
          b.aob=a;
          c.aob=a.aob;
          A d=new A().aob=new A();  //tricky assignement
          c=b;                      //one object eligible GC
          c.aob=null;
          System.gc();
     }
}

有两个对象符合垃圾回收条件,但一个很难理解。

A d=new A().aob=new A();

1) 这条线我认为它会变成这样

A d = new A().aob = new A();
          ^             ^
          O1            O2

      O1 --> O2 --> null
      ^
      |
d ----| 

2) 但真正在做的是这个(所以一个合格的对象)为什么会这样?

A d = new A().aob = new A();
          ^             ^
          O1            O2

      O1 --> O2 --> null
             ^
             |
d -----------| 

因为分配是从右到左关联的。

A d = ( new A().aob = new A() );

谁能解释一下? 谢谢

【问题讨论】:

  • 两点:第一,你的第二张图应该有O2 --> O1 --> null。其次,另一个符合gc条件的对象是A c = new A();中分配给cA的原始实例。大概你知道这个,但没有提到它,所以我想我会提到它。 :)

标签: java garbage-collection scjp ocpjp


【解决方案1】:

从右到左开始。首先执行new A() 并创建一个新对象。然后将其分配给另一个新对象A 的字段aob。最后d 引用属性aob。这意味着第二个对象A 符合垃圾回收条件。

是这样的:

A firstA = new A();
A secondA = new A();
secondA.aob = firstA;
A d = secondA.aob;

secondA 对象是内联创建的,因此没有对它的引用,它可以进行垃圾回收。

【讨论】:

  • A d = new A().aob = new A(); ---- 将等同于 --- A d = new A();新 A().aob = d;
【解决方案2】:

在这个例子中你会期待什么?

A a = new A();
A b = new A();
a.aob = b;
A d = a.aob;

d 是实例 a 还是实例 b

您是否会因为内联创建对象而期望它有所不同?

在这个例子中d肯定是对象b,所以对象a没有被引用并且可以被垃圾回收。

【讨论】:

    【解决方案3】:
    A d = new A().aob = new A();
    

    在 Java 中,赋值运算符是右关联的,即它们是从右到左计算的。而且,它们属于最低优先级运算符组。

    所以第二个 new 运算符(第二个相等的右边)首先被评估,我们得到一个新的 A 对象;假设是“a”。现在我们有:

    new A().aob = a;
    

    这里的诀窍是识别运算符的优先级。看这里:http://pages.cs.wisc.edu/~willb/cs302/spring-07/java-operator-precedence.pdf

    'new' 运算符和 '.'方法调用运算符具有相同的优先级,但它们的关联质量是相反的:'new' 是右关联的,而 '.'是左结合的。

    因此编译器首先将 new 运算符应用于“右操作数”,即此处的“A()”(在下一个操作数到位之前)。我们称新对象为b;我们有:

    A d = b.aob = a;
    

    编译器现在需要应用 '.'运算符优先(因为 '.' 的优先级高于 '=' 运算符)。我们将 'b.aob' 引用的对象称为 c

    A d = c = a;
    

    最后剩下的是赋值运算符,它们是右关联的(从右到左计算)。所以,a首先被分配给c(b.aob),然后c被分配给d

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-20
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多