【问题标题】:Weak references and anonymous classes弱引用和匿名类
【发布时间】:2016-07-20 10:02:05
【问题描述】:

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

问题 - 我认为 - 我有一个引用是匿名类。我担心如果我将匿名类存储为 WeakReference,它可能会很快被收集,如果我将匿名类存储为强引用,它将持有对构造匿名类的类的引用。

不知道我的解释是否清楚,所以这里是一段代码:

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' 的实例将永远不会被垃圾回收。

所以我的第一个问题:我的理解正确吗? 第二个问题:有没有办法让它工作还是我必须改变设计?

谢谢。

【问题讨论】:

    标签: java garbage-collection weak-references


    【解决方案1】:

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

    同样可以通过将匿名类替换为静态内部类或单独的类来实现。

    目前尚不清楚您为什么要为每个 Item 使用两个单独的弱引用。您可以简单地将项目本身保持在弱引用中,并对keycallback 进行强引用,当项目本身只能弱访问时,它们实际上会很弱。

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

    基本上,只有在需要发布“A”时才发布我的项目。

    那么WeakHashMap&lt;A, Callback&gt; 就是你想要的。只需确保 Callback 不引用 A

    【讨论】:

    • 哦,我不知道 lambda 没有保留实例,很有趣。而且你是对的,我没有想过将整个项目作为弱参考!很好的解决方案。谢谢!
    • 现在我想一想,如果我使用弱引用存储我的项目,我会不会遇到与我将回调存储为弱引用时相同的问题?我的意思是在我有机会使用它之前把它收集起来。我知道弱引用的原则(你不知道它们何时会被收集)但我想尽可能多地保留我的物品。基本上,只有在需要发布“A”时才发布我的项目。我是不是想多了,我还是会没事的,因为不经常收集弱裁判? (SoftReference 会有什么不同吗?)
    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多