Javafx - 是垃圾收集的ReadOnlyDoubleWrappers?

时间:2014-02-26 21:39:04

标签: java garbage-collection javafx

如果您阅读ReadOnyObjectWrapper的{​​{3}},您会看到getReadOnlyProperty()方法使用简单的单例实例方案,即

ReadOnlyPropertyImp readOnlyProperty;

public ReadOnlyDoubleProperty getReadOnlyProperty(){
    if(readOnlyProperty == null){
        readOnlyProperty = new ReadOnlyPropertyImp();
    }
    return readOnlyProperty;
}

其中ReadOnlyPropertyImp是扩展ReadOnlyDoubleProperty的嵌套类。但在我看来,如果我要做的话

ReadOnlyDoubleWrapper wrapper= new ReadOnlyDoubleWrapper();
ReadOnlyDoubleProperty property = wrapper.getReadOnlyProperty();

现在,wrapperproperty都不会被垃圾收集,因为每个都包含对另一个的强引用。这准确吗?

1 个答案:

答案 0 :(得分:0)

根据我的评论,如果对两个对象的所有引用超出范围,则值将为GC。看看这段代码:

public class Main
{
static WeakReference<StrongReference> wr1;
static WeakReference<StrongReference> wr2;

public static void main(String[] args) throws Exception {
    Main m = new Main();

    System.out.println(wr1.get() == null);
    System.out.println(wr2.get() == null);

    int count = 0;
    while (count < 5) {
        Thread.sleep(1000);
        //attempt to invoke GC
        System.out.println("GC Hint");
        System.gc();
        count ++;
    }

    System.out.println(wr1.get() == null);
    System.out.println(wr2.get() == null);
}

public Main() {
    wr1 = new WeakReference<StrongReference>( new StrongReference());
    wr2 = new WeakReference<StrongReference>( new StrongReference());
    wr1.get().setRef(wr2.get());
    wr2.get().setRef(wr1.get());

    System.out.println("SR 1 references - " + wr1.get().getRef().toString());
    System.out.println("SR 2 references - " + wr2.get().getRef().toString());
}


private class StrongReference {
    private Object myRef;

    public void setRef(Object o) {
        myRef = o;
    }

    public Object getRef() { 
        return myRef;
    }
}
}

输出:

SR 1 references - com.so.test.Main$StrongReference@c21495
SR 2 references - com.so.test.Main$StrongReference@1d5550d
false
false
GC Hint
GC Hint
GC Hint
GC Hint
GC Hint
true
true

在这段代码中,我有两个StrongReference类型的对象,它们相互引用。你会认为他们永远不会被GC,但他们可以。我将它们包装在WeakReference对象中,以在创建它们之后打破对它们的引用链,并允许GC获取它们。即使它们彼此引用,值仍将从WeakReference调用返回null到get(),因为GC已清除它们。我应该注意到GC可能在5秒循环期间没有运行。我只是提供一个提示JVM来执行GC,而不是实际调用,所以结果可能会有所不同