Java:使用弱引用进行堆栈

时间:2012-08-10 21:49:45

标签: java stack set weak-references weakhashmap

在Java中,有一个名为WeakHashMap的数据结构,它将弱引用存储为键。每当弱引用从内存中取出时,该条目将从地图中删除。

如果我有一个数据结构,例如Stack或Set我存储的弱引用,当弱引用从内存中取出时,它们的条目是否会被自动删除?

以下是存储弱引用的Stack的示例。

Stack<WeakReference<Object>> objStack = new Stack<WeakReference<Object>>();

2 个答案:

答案 0 :(得分:2)

是。您所描述的内容通常是弱引用的属性,而不是WeakHashMap具体。

来自the API

  

假设垃圾收集器在某个时间点确定对象是弱可达的。那时它会原子地清除对该对象的所有弱引用......

答案 1 :(得分:1)

迟到总比不到好。

弱引用不是这样工作的。 WeakReference对象将始终存在,但是其get()方法可能返回原始对象或null(如果原始对象是GC:ed)。

这意味着您的堆栈将始终包含一个WeakReference对象。

这是我进行的详细测试(但是,这取决于JVM在中间执行GC,这可能会或可能不会在“命令时”发生-如果没有,请尝试添加更多System.gc():s发生):

public static void main(String[] args) {
    // Set up
    Object object = new Object();
    final WeakReference<Object> weakReference = new WeakReference<>(object);
    final Stack<WeakReference<Object>> references = new Stack<>();      
    references.add(weakReference);

    // Before
    System.out.println("Before:");

    references.forEach(r -> {
        System.out.println("Reference: " + r);
        System.out.println("Object: " + r.get());
    });

    // GC
    object = null;

    System.gc();
    System.gc();
    System.gc();

    // After
    System.out.println("After:");
    references.forEach(r -> {
        System.out.println("Reference: " + r);
        System.out.println("Object: " + r.get());
    });
}

输出:

Before:
Reference: java.lang.ref.WeakReference@238e0d81
Object: java.lang.Object@31221be2
After:
Reference: java.lang.ref.WeakReference@238e0d81
Object: null

您最好的方法可能是忽略“ {弹出}”后get()返回null的条目。

侧面说明:我的第一个测试是使用String对象,它从未使用过GC:ed。这是因为Java中的字符串是“ interned”的(请参见String.intern()),这意味着有隐藏的静态字符串缓存可以重用。字符串永远不会被GC:ed,除非该字符串池已满(或沿这条线...)。我认为字符串是唯一具有这种“特殊”特征的Java对象,但我建议始终使用定制对象在WeakReference中,以确保其正确获得了GC:ed。