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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With