Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java fixed memory map

Is there a simple, efficient Map implementation that allows a limit on the memory to be used by the map.

My use case is that I want to allocate dynamically most of the memory available at the time of its creation but I don't want OutOFMemoryError at any time in future. Basically, I want to use this map as a cache, but but I wanna avoid heavy cache implementations like EHCache. My need is simple (at most an LRU algorithm)

I should further clarify that objects in my cache are char[] or similar primitives that will not hold references to other objects.

I can put an upper limit on max size for each entry.

like image 350
juber Avatar asked May 31 '10 03:05

juber


2 Answers

You can use a LinkedHashMap to limit the number of entries in the Map:

removeEldestEntry(Map.Entry<K,V> eldest): Returns true if this map should remove its eldest entry. This method is invoked by put and putAll after inserting a new entry into the map. It provides the implementor 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.

Sample use: this override will allow the map to grow up to 100 entries and then delete the eldest entry each time a new entry is added, maintaining a steady state of 100 entries.

private static final int MAX_ENTRIES = 100;

protected boolean removeEldestEntry(Map.Entry eldest) {
    return size() > MAX_ENTRIES;
}

Related questions

  • How do I limit the number of entries in a java hashtable?
  • Easy, simple to use LRU cache in java
  • What is a data structure kind of like a hash table, but infrequently-used keys are deleted?
like image 159
polygenelubricants Avatar answered Sep 28 '22 16:09

polygenelubricants


For caches, a SoftHashMap is much more appropriate than a WeakHashMap. A WeakhashMap is usually used when you want to maintain an association with an object for as long as that object is alive, but without preventing it from being reclaimed.

In contrast, a SoftReference is more closely involved with memory allocation. See No SoftHashMap? for details on the differences.

WeakHashMap is also not usually appropriate as it has the association around the wrong way for a cache - it uses weak keys and hard values. That is, the key and value are removed from the map when the key is cleared by the garbage collector. This is typically not what you want for a cache - where the keys are usually lightweight identifiers (e.g. strings, or some other simple value type) - caches usually operate such that the key/value is reclaimed when the value reference is cleared.

The Commons Collections has a ReferenceMap where you can plug in what types of references you wish to use for keys and values. For a memory-sensitive cache, you will probably use hard references for keys, and soft references for values.

To obtain LRU semantics for a given number of references N, maintain a list of the last N entries fetched from the cache - as an entry is retrieved from the cache it is added to the head of the list (and the tail of the list removed.) To ensure this does not hold on to too much memory, you can create a soft reference and use that as a trigger to evict a percentage of the entries from the end of the list. (And create a new soft reference for the next trigger.)

like image 21
mdma Avatar answered Sep 28 '22 16:09

mdma