Java垃圾可以在范围结束前收集变量吗?
作者:互联网
假设我们有这样的程序:
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永远不会被读或写,所以变量实际上已经死了,指针值可以被丢弃.如果所有引用都很强,这种“优化”将是有效的,但是当引入软,弱和幻像引用的概念以及终结器时,推理就会分崩离析.同样作为类比,因为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,reference,garbage-collection,weak-references 来源: https://codeday.me/bug/20190519/1134546.html