Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/375.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这是不是垃圾收集?_Java_Multithreading_Garbage Collection - Fatal编程技术网

Java 这是不是垃圾收集?

Java 这是不是垃圾收集?,java,multithreading,garbage-collection,Java,Multithreading,Garbage Collection,下面是一些代码: public class A { private volatile B b; public void methodC() { b.doSomething(); } public void setB(B newB) { this.b = newB; } } “线程1”正在通过执行methodC()执行b.doSomething() 同时“线程2”将一个新的B对象设置为“B” 我的问题是: 虽然“b”之前引用的对象上的doSomething

下面是一些代码:

public class A {
  private volatile B b;

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

  public void setB(B newB) {
    this.b = newB;
  }
}
“线程1”正在通过执行methodC()执行b.doSomething()

同时“线程2”将一个新的B对象设置为“B”

我的问题是:


虽然“b”之前引用的对象上的doSomething()方法仍在执行,但该对象是否可以被垃圾收集?

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

尽管在下面检查Jon Harrop的答案,了解
b
可能是
GC
'd的情况

虽然“b”之前引用的对象上的doSomething()方法仍在执行,但该对象是否可以被垃圾收集

是的,以前由“b”引用的对象可能被垃圾收集,即使其上的
doSomething()
方法仍在执行

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


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

我认为没有直接或派生的引用来自“线程1”的前一个引用对象。我认为GC文档中的“reachable”意味着必须有某个线程具有对它的任何直接引用或派生引用。我可以确定的任何引用?必须有对线程堆栈中对象的引用,才能调用成员函数。还可以如何调用此函数?请查看表示线程堆栈上单个帧的
StackFrame
类。它包含对
这个
对象的引用。你说得对。我发现:我误解了GC中的可达性。我认为所有的可达性都来自变量,而不是调用堆栈。谢谢你提供的细节:-)+1啊,我现在明白你的意思了。我想我在想
这个
指针会在
doSomething
中使用,但你是对的-如果在该函数中没有对
这个
的引用,那么没有什么可以阻止它成为GC'd。即使使用了它,在
doSomething
功能中最后一次使用后,它仍然可以回收。