弱引用和匿名 类
Weak references and anonymous classes
我的情况是我有一个缓存一些引用的静态列表。由于这是一个静态列表,我想使用 WeakReference 这样我就不会无用地将我的对象保存在内存中。
我认为我遇到的问题是其中一个参考文献是匿名的 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
使用两个单独的弱引用。您可以简单地将项目本身保持在弱引用中,并具有对 key
和 callback
的强引用,当项目本身仅弱可达时,它们实际上是弱引用。
一般来说,您应该从 GC 根推理路径。如果一个对象只能从具有引用路径的 GC 根访问,其中即使一个引用是弱的,那么整个子图也只能是弱可达的,因此有资格被收集。
Basically, to have my item released only when 'A' need to be released.
那么WeakHashMap<A, Callback>
就是你想要的。只需确保 Callback
不引用 A
.
我的情况是我有一个缓存一些引用的静态列表。由于这是一个静态列表,我想使用 WeakReference 这样我就不会无用地将我的对象保存在内存中。
我认为我遇到的问题是其中一个参考文献是匿名的 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
使用两个单独的弱引用。您可以简单地将项目本身保持在弱引用中,并具有对 key
和 callback
的强引用,当项目本身仅弱可达时,它们实际上是弱引用。
一般来说,您应该从 GC 根推理路径。如果一个对象只能从具有引用路径的 GC 根访问,其中即使一个引用是弱的,那么整个子图也只能是弱可达的,因此有资格被收集。
Basically, to have my item released only when 'A' need to be released.
那么WeakHashMap<A, Callback>
就是你想要的。只需确保 Callback
不引用 A
.