是否可以在对 WeakReference.get() 的两次后续调用之间对对象进行垃圾回收?

Can object be garbage collected between two subsequent calls to WeakReference.get()?

我有时会在一些库 API 中看到这种代码,而且只是在某人的代码中:

class SomeClass {

    private WeakReference<SomeObject> objectWeakReference; // initialized elsewhere

    public boolean isObjectAttached() {
        return objectWeakReference.get() != null;
    }

    public SomeObject getObject() {
        return objectWeakReference.get();
    }

}

public void checkAndGetWeakReference() {
    SomeClass someClass = new SomeClass();
    if (someClass.isObjectAttached()) {
        someClass.getObject().doSomethingDirectlyOnReturnedObject(); // can the returned reference be null here ?
    }
}

而且我总是担心是否会出现 NullPointerException 异常,假设此时没有对底层对象的强引用。

我真的不知道垃圾收集器到底什么时候可以开始从内存中删除对象以及它与基本线程流有何关联。

如果有人能阐明这个特定主题,那就太好了and/or提供一些有关该主题的信息。

P.S。我个人只会获得一次参考并将其分配给强参考。问题的重点是得到一些证明上面的代码是错误的。

根据 java 文档。你不应该依赖垃圾收集器。它不确定何时执行。尽管您正在明确尝试 System.gc()

JVM 垃圾收集器的优先级一直是最低的。当 JVM 空闲时或当您的程序即将 运行 内存不足时,它可以执行 GC。

在其他情况下,您的程序将退出。它将在从 JVM 内存中清除之前被垃圾收集。

请参考java文档了解GC的详细解释。

http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

WeakReference(以及 SoftReference)的全部要点是被引用的对象可能会在 任何 不存在对该对象的强引用时进行 gc。

因为在 isObjectAttached() returns 时不存在强引用,所以可以在它实际执行 getObject() 之前对其进行垃圾回收。对于这个用例,整个 idom 都是错误的。

唯一安全的方法是获取引用(例如局部变量)然后然后检查它是否为空。在这种情况下,对象不能被垃圾回收,因为局部变量 强引用。

垃圾收集器内部有其启发式方法来收集 soft/weak/phantom 引用。它不会在后续的 GC 调用中收集这些对象。它跟踪这些对象,直到它达到启发式的阈值,GC 不允许收集这些引用。

我想对所有答案进行补充。

当您调用以下方法时,您的对象可以为 null :

public SomeObject getObject() {
        return objectWeakReference.get();
    }

关于此对象的垃圾回收。 如果您执行以下操作:

public static void main(String args[]) {
     SomeClass oSomeClass = new SomeClass();

     // this one is strong reference "obj"
     // this object can be null. Best practice is to null check before you use it.
    // Or i will suggest to call isObjectAttached() method before you use it
     Object obj = oSomeClass.getObject(); 
}

当你做 obj = null;上述语句后代码中的某处。

此对象内存可用于垃圾回收。每当 JVM 需要清理内存时。是的,它可以收集这个对象。

关于您要求的代码证明。

public boolean isObjectAttached() {
        return objectWeakReference.get() != null;
    }

此方法是为您检查此对象是否存在于内存中或是否具有对您有效的引用。

如果它 returns 为真,您将永远不会得到空指针异常。

但如果您不使用此方法,我建议您在使用对象之前始终使用 null 检查。

希望我的方向是正确的并且我的回答有一定道理。请相应回复。

我们都在这里学习 ;-) 享受 Java、OOP 概念。