java - Java 可以在作用域结束前收集变量吗?

标签 java reference garbage-collection weak-references

假设我们有这样一个程序:

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 点( block 作用域结束)变得不可强访问?

这个问题的答案将影响对 doSomething() 的调用是否保证能够访问 Activity 的 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.

由于 bt 变量在第 2 点后将不再使用,Java 可以自由清除该变量,从而使 BigThing 对象只能弱可达。

关于java - Java 可以在作用域结束前收集变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39285108/

相关文章:

Java字节数组压缩

c - 未解析的外部符号、多个项目、Visual C++ 链接器错误?

ruby - GC.disable 的任何性能缺点?

.net - 分而治之大对象的 GC 性能

java - 大堆上最坏情况垃圾收集持续时间大约是多少

c# - Java 套接字断开连接报告与 C# 断开连接

java - 检查约束(或更好的东西)

Java 我 : easiest way to format strings?

.net - 如何在 Visual Studio 中通过 F5 部署加载项库?

javascript更改对象变量引用