假设我有一个如下代码
class XXX {
private Date date = new Date();
public void doSomething() {
new Thread(new Runnable() {
@Override
public void run() {
// do a long running operation and use the date variable
}
}).start();
}
}
我有一个XXX类的实例,我在上面调用了doSomething()。没有其他代码再引用XXX实例。
我的问题是:当启动的线程正在运行时,GC是否允许从堆中删除XXX实例?是否允许GC从堆中删除日期实例?
据我所知,当匿名类使用局部变量时,其值将通过编译器创建的构造函数进行复制。但是对于像上面这样的封闭类的实例字段也是如此吗?如果是,那么xxx实例可能被垃圾收集。
请详细说明一下。
答案 0 :(得分:12)
表达式
new Runnable() {
@Override
public void run() {
// do a long running operation and use the date variable
}
}
实例方法中的 将生成实现Runnable
的匿名内部类的实例。因为实例是内部类,所以它具有对外部实例XXX
实例的引用。
Thread
start()
将立即开始在新线程中执行Runnable#run()
代码。因此,Runnable
无法进行GC。因此Runnable
实例引用的任何对象都不能被GC,即。 XXX
实例。
答案 1 :(得分:0)
new Runnable() {
@Override
public void run() {
// do something
}
}
此进程是实现Runnable Interface的匿名内部类的实例。指针将引用Thread#target
字段。由于这个例子,存在DE引用并因此导致问题。 Java在编译之前检查可点引用。我尝试编译你的代码,这个类很容易访问,所以它不需要是GC。因此,如果您尝试创建内部类,则可以避免引用外部或封闭类的实例。
答案 2 :(得分:0)
new Runnable() {
@Override
public void run() {
// long running code separately using different value stack
}
}