带条件/超时的弱引用

时间:2012-10-19 09:43:35

标签: java garbage-collection weak-references

是否可以在Java中创建一个弱引用,只有当指定的条件返回true时才能将其对象发送到垃圾回收器?

假设我有一些缓存可以将ID号映射到某些数据:

Map<Integer, SomeData> cache = new HashMap<>();

SomeData有两个重要方法 - void updateTime(),它只是将内部变量设置为当前时间,而boolean canBeDeleted()则检查对象是否已在最后使用10分钟(简单地通过比较当前时间和节省的时间再加上10分钟)。如果它在一段时间内没有被使用,则该方法返回true,并且可以从缓存中删除该对象...

但是,当我使用弱引用而不是强引用创建缓存时:

Map<Integer, WeakReference<SomeData>> cache = new HashMap<>();

然后唯一的WeakReference检查可能是对该对象的强引用,但我想如果它也检查了我的条件canBeDeleted()并且如果它返回{{1则没有删除引用}}。有办法怎么做?

(最重要的是,有一个内存泄漏,我不知道如何解决它...当WeakReference中的对象被删除时,地图仍然包含不必要的键/值对。)

提前致谢。

2 个答案:

答案 0 :(得分:2)

您可以使用LinkedHashMap#removeEldestEntry虽然它没有提供基于条目在缓存中的时间来删除的方法,它确实为您提供了一种根据条目是否被访问来删除条目的方法。

  

它为实施者提供了在每次添加新条目时删除最旧条目的机会。如果映射表示缓存,这将非常有用:它允许映射通过删除过时条目来减少内存消耗。

protected boolean removeEldestEntry(Map.Entry<K,V> eldest) {
  return size() > limit;

另请记住,您需要使用accessOrder true初始化LinkedHashMap。

  

accessOrder - 排序模式 - 对于访问顺序为true,对于插入顺序为false。

所以把它们放在一起就应该如下所示

public class Cache<K, V> extends LinkedHashMap<K, V> {
    private final int MAX_ENTRIES = 100;
    public Cache() {
        super(16, 0.75f, true);// accessOrder is true
    }
    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        return size() > MAX_ENTRIES;
    }
}

答案 1 :(得分:0)

您可以删除条件为真的缓存中的密钥。