对象字段的完成

Finalization of object fields

我很难理解 Java SE 8 语言规范第 12.6.1 和 12.6.2 节的含义。我正在使用 Java 对象管理本机对等体的产品,因此正确完成(直到我们有机会重写引用队列)很重要。

很明显,从规范来看,终结器可能 运行 乱序。这是我遇到困难的可达性。

我相信规范是这样说的:

class A {
    public Object o = new Object()
    protected synchronized void finalize() throws Throwable { o = null; }
}

class B {
    A a = new A()
    protected void finalize() throws Throwable {
        a.getClass()   // always works: a cannot be null.
        a.o.getClass() // might NPE: a's finalizer might have been run
    }
}

class C {
    A a = new A()
    protected void finalize() throws Throwable {
        synchronized (a) {
            a.getClass()   // always works: a cannot be null.
            a.o.getClass() // always works: a.o cannot be null.
        }
    }
}

上面有4个断言。我非常感谢确认它们是真实的,或者解释为什么一个或多个是错误的。

如果A.finalize先获取锁,那么a.o.getClass()即使在C中也会NPE。最后的断言是错误的。

可达性方面 可以这样想:假设 AC 是循环可达的,那么它们将在“相同的时间”达到不可达性时间”。因此,A 必须在 C.

之前完成是不合理的

我猜 直接 修复可能是 A 的引用计数。但是,靠GC来清理非内存资源也不会好到哪里去。