Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I efficiently cache objects in Java using available RAM?

I need to cache objects in Java using a proportion of whatever RAM is available. I'm aware that others have asked this question, but none of the responses meet my requirements.

My requirements are:

  • Simple and lightweight
  • Not dramatically slower than a plain HashMap
  • Use LRU, or some deletion policy that approximates LRU

I tried LinkedHashMap, however it requires you to specify a maximum number of elements, and I don't know how many elements it will take to fill up available RAM (their sizes will vary significantly).

My current approach is to use Google Collection's MapMaker as follows:

Map<String, Object> cache = new MapMaker().softKeys().makeMap();

This seemed attractive as it should automatically delete elements when it needs more RAM, however there is a serious problem: its behavior is to fill up all available RAM, at which point the GC begins to thrash and the whole app's performance deteriorates dramatically.

I've heard of stuff like EHCache, but it seems quite heavy-weight for what I need, and I'm not sure if it is fast enough for my application (remembering that the solution can't be dramatically slower than a HashMap).

like image 239
sanity Avatar asked Sep 10 '25 21:09

sanity


2 Answers

I've got similar requirements to you - concurrency (on 2 hexacore CPUs) and LRU or similar - and also tried Guava MapMaker. I found softValues() much slower than weakValues(), but both made my app excruciatingly slow when memory filled up.

I tried WeakHashMap and it was less problematic, oddly even faster than using LinkedHashMap as an LRU cache via its removeEldestEntry() method.

But by the fastest for me is ConcurrentLinkedHashMap which has made my app 3-4 (!!) times faster than any other cache I tried. Joy, after days of frustration! It's apparently been incorporated into Guava's MapMaker, but the LRU feature isn't in Guava r07 at any rate. Hope it works for you.

like image 167
Jonathan Avatar answered Sep 12 '25 12:09

Jonathan


I've implemented serval caches and it's probably as difficult as implementing a new datasource or threadpool, my recommendation is use jboss-cache or a another well known caching lib. So you will sleep well without issues

like image 34
stacker Avatar answered Sep 12 '25 13:09

stacker