弱引用和匿名 类

Weak references and anonymous classes

我的情况是我有一个缓存一些引用的静态列表。由于这是一个静态列表,我想使用 Wea​​kReference 这样我就不会无用地将我的对象保存在内存中。

我认为我遇到的问题是其中一个参考文献是匿名的 class。我担心的是,如果我将匿名 class 存储为弱引用,它可能会很快被收集,如果我将匿名 class 存储为强引用,它将持有对 class 构造了匿名 class.

不知道我解释的清楚了没有,这里贴一段代码:

public interface Callback {
    void call();
}

public class A {
    public void doIt() {
        B.register(this, new Callback() {
            public void call() {
                // do something
            }
        });
    }
}

public class B {
    private static final List<Item> ITEMS = new LinkedList<>();

    public static void register(Object key, Callback callback) {
        Item item = new Item();
        item.key = new WeakReference<>(key);

        // ??
        item.callback = new WeakReference<>(callback);

        ITEMS.add(item);
    }

    private static class Item {
        private WeakReference<Object> key;
        private WeakReference<Callback> callback;
    }
}

基本上,如果 Item 'callback' 是一个弱引用,它可能在我有机会使用它之前就被垃圾回收了。 如果 Item 'callback' 是标准引用,则 'A' 的实例将永远不会被垃圾回收。

那么我的第一个问题:我的理解对吗? 第二个问题:有没有办法让它工作或者我必须改变设计?

谢谢。

如果 Callback 是函数式接口,您可以改用 lambda。 Lambda 只捕获它们引用的变量。因此,如果 lambda 是纯函数、静态方法引用或仅引用局部变量,它将不会捕获 this。如果您引用 this,一个实例方法或实例字段,那么它将捕获。

同样可以通过将匿名 class 替换为静态内部 class 或单独的 class.

来实现

不清楚为什么每个 Item 使用两个单独的弱引用。您可以简单地将项目本身保持在弱引用中,并具有对 keycallback 的强引用,当项目本身仅弱可达时,它们实际上是弱引用。

一般来说,您应该从 GC 根推理路径。如果一个对象只能从具有引用路径的 GC 根访问,其中即使一个引用是弱的,那么整个子图也只能是弱可达的,因此有资格被收集。

Basically, to have my item released only when 'A' need to be released.

那么WeakHashMap<A, Callback>就是你想要的。只需确保 Callback 不引用 A.