Reputation: 558
I'm trying to use LinkedHashMap as a local FIFO cache solution overwriting its removeEldestEntry method to keep size fixed:
Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, .75F, false) {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_CACHE_SIZE;
}
};
but when I constantly add new entries to the map monitoring process memory I see it keeps growing until max virtual machine memory is used though map size doesn't increase.
Is it by design? Why does it need more memory if old values are discarded and size of the map is limited?
UPDATE: as requested I'm attaching full code:
@Test
public void mapMemory() {
final int MAX_CACHE_SIZE = (int) 1E3;
Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, 1F, false) {
protected boolean removeEldestEntry(Map.Entry eldest) {
return size() > MAX_CACHE_SIZE;
}
};
for (long i = 0; i < 1E10; i++) {
lhm.put("key_" + i, "VALUE");
}
}
Upvotes: 3
Views: 4325
Reputation: 61
A blog post explaining memory leak issue with LinkedHashMap in multi-thread context
https://hoangx281283.wordpress.com/2012/11/18/wrong-use-of-linkedhashmap-causes-memory-leak/
Upvotes: 2
Reputation: 31730
If you need random access to the collection's contents then it's not really a FIFO.
It should be noted that collections don't store objects though, they store references to objects which is an important distinction. Storing the same object in 2 different collections won't have significant memory overhead so maybe your best solution it to store the same object into both a Queue and a Map, use the Queue when you need FIFO behaviour an the Map when you need random access.
You do have to remember to remove the object from both collections when you're done with it though, otherwise it won't be GC'd.
Upvotes: 0
Reputation: 3353
The second parameter in your constructor defines loadFactor, multiplied by your 1st parameter (map size) it gives you the value (size) that triggers the resize of you map. So in your case you should (probably) use loadFactor = 1.
EDIT:
Your memory leak is caused by something that you DON'T show us, your code as above will NEVER cause a memory leak.
Check where you may be keeping references to old values/objects. Map in itself would NOT cause memory leak - if it did ALL systems using maps (and there are lots of them) would be crashing every few hours.
Upvotes: 0