Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Weak reference with a condition / timeout

is it possible in Java to create a weak reference whose object can be sent to garbage collector only if a specified condition returns true?

Let's say that I have something like a cache which maps ID numbers to some data:

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

SomeData have two important methods - void updateTime(), which just sets an internal variable to current time, and boolean canBeDeleted(), which checks if the object have or haven't been used in last 10 minutes (simply by comparing current time and the saved time plus 10 minutes). If it haven't been used for this certain amount of time, the method returns true and the object can be removed from the cache...

However, when I create a cache with weak references instead of strong:

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

Then the only thing WeakReference checks are probably possible strong references to the object, but I would like if it also checked my condition canBeDeleted() and didn't remove the reference if it returned false. Is there a way how to do this?

(On top of that, there's a memory leak and I'm not sure how to solve it... When the object inside the WeakReference is deleted, the map still contains unnecessary key/value pair).

Thanks in advance.

like image 315
Martin Majer Avatar asked Oct 19 '12 09:10

Martin Majer


1 Answers

You can use LinkedHashMap#removeEldestEntry though It does not provide you way to remove based on amount of time entry is inside Cache, it does provide you a way to remove entries based on whether it was accessed or not.

It provides the implementer with the opportunity to remove the eldest entry each time a new one is added. This is useful if the map represents a cache: it allows the map to reduce memory consumption by deleting stale entries.

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

Also remember you need to initialize LinkedHashMap with accessOrder true.

accessOrder - the ordering mode - true for access-order, false for insertion-order.

So putting it all together source should be like below

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;
    }
}
like image 62
Amit Deshpande Avatar answered Oct 22 '22 22:10

Amit Deshpande