这是垃圾收集还是没收?

时间:2012-04-18 13:11:10

标签: java multithreading garbage-collection

以下是一些代码:

public class A {
  private volatile B b;

  public void methodC() {
    b.doSomething();
  }

  public void setB(B newB) {
    this.b = newB;
  }
}

'Thread 1'通过执行methodC()执行b.doSomething()。

同时'线程2'将新的B对象设置为'b'。

我的问题是:

先前由'b'引用的对象是否可以被垃圾收集,尽管它上面的doSomething()方法仍在执行?

2 个答案:

答案 0 :(得分:7)

不,因为要调用成员函数,您需要引用该对象。因此,调用b.doSomething()的线程将持有一个引用,从而防止垃圾回收。

虽然请查看下面针对b可能为GC'的情况的Jon Harrop的回答。

答案 1 :(得分:1)

  

先前由'b'引用的对象是否可以被垃圾收集,尽管它上面的doSomething()方法仍在执行?

是的,先前由'b'引用的对象可能是垃圾收集的,即使它上面的doSomething()方法仍在执行。

在执行其中一个方法时,您可能希望this可以访问,因为方法是隐式传递this指针,您可能会认为它总是溢出到堆栈。但是,许多优化可以改变这一点,并从GC看到的全局根集中删除this

例如,如果doSomething方法的主体以不需要this的代码结束并且方法被内联,那么this可能不会从寄存器溢出到堆栈或其堆栈槽可能被覆盖。在任何一种情况下,即使执行仍在this内,GC也不会再看到doSomething,因此,this可能会被垃圾收集。