Lightweight Java Object cache API

JavaCaching

Java Problem Overview


Question

I'm looking for a Java in-memory object caching API. Any recommendations? What solutions have you used in the past?

Current

Right now, I'm just using a Map:

Map cache = new HashMap<String, Object>();
cache.put("key", value);

Requirements

I need to extend the cache to include basic features like:

  • Max size
  • Time to live

However, I don't need more sophisticated features like:

  • Access from multiple processes (caching server)
  • Persistence (to disk)

Suggestions

In-Memory caching:

  • Guava CacheBuilder - active development. See this presentation.
  • LRUMap - Config via API. No TTL. Not purpose built for caching.
  • whirlycache - XML config. Mailing list. Last updated 2006.
  • cache4j - XML config. Documentation in Russian. Last updated 2006.

Enterprise caching:

  • JCS - Properties config. Extensive documentation.
  • Ehcache - XML config. Extensive documentation. By far the most popular according to Google hits.

Java Solutions


Solution 1 - Java

EHCache is very nice. You can create an in memory cache. Check out their code samples for an example of creating an in memory cache. You can specify a max size, and a time to live.

EHCache does offer some advanced features, but if your not interested in using them - don't. But it's nice to know they are there if your requirements ever change.

Here is an in memory cache. Created in code, with no configuration files.

CacheManager cacheManager = CacheManager.getInstance();
int oneDay = 24 * 60 * 60;
Cache memoryOnlyCache = new Cache("name", 200, false, false, oneDay, oneDay);
cacheManager.addCache(memoryOnlyCache);

Creates a cache that will hold 200 elements, and has a ttl of 24 hours.

Solution 2 - Java

I really like the MapMaker that comes with Google Guava (API)

The JavaDoc has a pretty neat example that demonstrates both its ease of use and its power:

ConcurrentMap<Key, Graph> graphs = new MapMaker()
   .concurrencyLevel(32)
   .softKeys()
   .weakValues()
   .expiration(30, TimeUnit.MINUTES)
   .makeComputingMap(
       new Function<Key, Graph>() {
         public Graph apply(Key key) {
           return createExpensiveGraph(key);
         }
       });

Furthermore, release 10.0 of Guava introduced the much more extensive com.google.common.cache package (there's a nice wiki entry on how to use them).

Solution 3 - Java

You can also check out my little cache library called KittyCache at:

https://github.com/treeder/kitty-cache

There are some performance benchmarks vs ehcache.

It's used in the SimpleJPA project as a second level cache.

Solution 4 - Java

You can check out LinkedHashMap to implement a simple cache without third party jars:

    Map <String, Foo> cache = new LinkedHashMap<String, Foo>(MAX_ENTRIES + 1, .75F, true) {

        public boolean removeEldestEntry(Map.Entry<String, Foo> eldest) {
            return size() > MAX_ENTRIES;
        }
    };

then you can get from the cache like

    Foo foo = cache.get(key);
    if (foo == null && !cache.containsKey(key)) {
        try {
            FooDAO fooDAO = DAOFactory.getFooDAO(conn);
            foo = fooDAO.getFooByKey(key);
            cache.put(key, foo);
        } catch (SQLException sqle) {
            logger.error("[getFoo] SQL Exception when accessing Foo", sqle);
        }
    }

rest left as exercise for reader :)

Solution 5 - Java

Guava's MapMaker has been replaced by their CacheBuilder class.

Solution 6 - Java

JCS is tried and true. Even though it is light as far as caching mechanisms go, you might dig into the actual code and mimic what they do with HashMap under the covers to exactly what you need and no more. You seem to have a pretty good idea of what you are looking for.

Solution 7 - Java

memcached has client for Java. http://www.danga.com/memcached/ Requires separate process to be a caching server, but powerful thing.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChase SeibertView Question on Stackoverflow
Solution 1 - JavaSteve KView Answer on Stackoverflow
Solution 2 - JavaJoachim SauerView Answer on Stackoverflow
Solution 3 - JavaTravis ReederView Answer on Stackoverflow
Solution 4 - JavaJeeBeeView Answer on Stackoverflow
Solution 5 - JavaBohemianView Answer on Stackoverflow
Solution 6 - JavaIchorusView Answer on Stackoverflow
Solution 7 - JavaZorkusView Answer on Stackoverflow