Java 可以在范围结束之前对变量进行垃圾回收吗?
Can Java garbage collect variables before end of scope?
假设我们有这样一个程序:
void main() {
// Point 0
BigThing bt = new BigThing();
// Point 1
WeakReference<BigThing> weak = new WeakReference<>(bt);
// Point 2
doSomething(weak);
// Point 3
}
void doSomething(...) { ... }
我们知道,对 BigThing
对象的弱引用无法阻止对象在变得不再强可达时被垃圾回收。
我的问题是关于局部变量 bt
,它是对 BigThing
对象的强引用。 对象是在第 2 点(就在调用 doSomething()
之前)还是在第 3 点(块范围结束)变得不可强访问?
这个问题的答案将影响对doSomething()
的调用是否保证能够访问到活的BigThing
对象,或者底层对象是否可以在函数调用期间死亡。
我不确定,因为您可能会争辩说,在第 2 点之后,局部变量 bt
再也不会被读取或写入,因此该变量实际上已经死了,指针值可以被丢弃。如果所有引用都是强引用,这个 "optimization" 是有效的,但是当引入软引用、弱引用和虚引用以及终结器的概念时,推理就会分崩离析。同样打个比方,因为 C++ 有析构函数,一个值必须在作用域的末尾被析构,不能向前移动到最后使用的点。
我会说该对象在第 2 点是可收集的,在 JLS section 12.6.1 中使用以下语言:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
由于在第 2 点之后将不再使用 bt
变量,Java 可以自由清除该变量,从而使 BigThing 对象只能弱可达。
Java 9引入Reference.reachabilityFence来解决这个case,当然这也暗示了它本来就存在
假设我们有这样一个程序:
void main() {
// Point 0
BigThing bt = new BigThing();
// Point 1
WeakReference<BigThing> weak = new WeakReference<>(bt);
// Point 2
doSomething(weak);
// Point 3
}
void doSomething(...) { ... }
我们知道,对 BigThing
对象的弱引用无法阻止对象在变得不再强可达时被垃圾回收。
我的问题是关于局部变量 bt
,它是对 BigThing
对象的强引用。 对象是在第 2 点(就在调用 doSomething()
之前)还是在第 3 点(块范围结束)变得不可强访问?
这个问题的答案将影响对doSomething()
的调用是否保证能够访问到活的BigThing
对象,或者底层对象是否可以在函数调用期间死亡。
我不确定,因为您可能会争辩说,在第 2 点之后,局部变量 bt
再也不会被读取或写入,因此该变量实际上已经死了,指针值可以被丢弃。如果所有引用都是强引用,这个 "optimization" 是有效的,但是当引入软引用、弱引用和虚引用以及终结器的概念时,推理就会分崩离析。同样打个比方,因为 C++ 有析构函数,一个值必须在作用域的末尾被析构,不能向前移动到最后使用的点。
我会说该对象在第 2 点是可收集的,在 JLS section 12.6.1 中使用以下语言:
Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a Java compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.
由于在第 2 点之后将不再使用 bt
变量,Java 可以自由清除该变量,从而使 BigThing 对象只能弱可达。
Java 9引入Reference.reachabilityFence来解决这个case,当然这也暗示了它本来就存在