我有时会在某些库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,假设此时没有对底层对象的强引用。
我真的不知道垃圾收集器何时可以开始从内存中删除对象,以及它如何与基本线程流相关联。
如果有人能够阐明这一特定主题和/或提供有关该主题的一些信息,那就太好了。
P.S。我个人只会参考一次并将其分配给强有力的参考。问题的关键是得到一些证据证明上面的代码是错误的。
答案 0 :(得分:3)
WeakReference(以及SoftReference)的重点在于,在任何时,引用的对象可能是gc,并且不存在对该对象的强引用。
由于isObjectAttached()返回时不存在强引用,因此可以在实际执行getObject()之前对其进行垃圾回收。对于这个用例,整个idom是错误的。
唯一安全的方法是首先获取引用(例如,获取本地变量),然后然后将其检查为null。在这种情况下,对象不能被垃圾收集,因为局部变量 是强引用。
答案 1 :(得分:0)
根据java doc。你不应该依赖垃圾收集器。它不知道什么时候会被执行。虽然您正在尝试显式System.gc()
它始终是JVM垃圾收集器的最低优先级。当JVM空闲或程序即将耗尽时,它可以执行GC。
在其他情况下,您的程序将退出。它将在从JVM内存中刷出之前进行垃圾回收。
请参阅javadoc以获取GC的详细说明。
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html
答案 2 :(得分:0)
我想在所有答案中添加一些内容。
当您调用以下方法时,您的对象可以为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;
}
此方法用于检查此对象是否存在于内存中,或者它是否具有有效的参考。
如果返回true,则永远不会得到nullpointer异常。
但如果您不使用此方法,我建议您在使用对象之前始终使用空检查。
希望我的方向正确,并在我的回答中有所作为。请相应回复。
我们都在这里学习;-) 享受Java,OOP概念。
答案 3 :(得分:-3)
垃圾收集器内部有其启发式来收集软/弱/幻像引用。它不会在后续GC调用中收集这些对象。它跟踪这些对象,直到达到启发式的阈值,GC不允许收集这些引用。