17
private Cache<Long, Response> responseCache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

I am expecting that response objects that are not send to client within 10 minutes are expired and removed from cache automatically but I notice that Response objects are not always getting expired even after 10, 15, 20 minutes. They do get expire when cache is being populated in large numbers but when the system turn idle, something like last 500 response objects, it stops removing these objects. Can someone help to understand this behavior? Thank you

Mark1234
  • 589
  • 2
  • 8
  • 24

1 Answers1

34

This is specified in the docs:

If expireAfterWrite or expireAfterAccess is requested entries may be evicted on each cache modification, on occasional cache accesses, or on calls to Cache.cleanUp(). Expired entries may be counted by Cache.size(), but will never be visible to read or write operations.

And there's more detail on the wiki:

Caches built with CacheBuilder do not perform cleanup and evict values "automatically," or instantly after a value expires, or anything of the sort. Instead, it performs small amounts of maintenance during write operations, or during occasional read operations if writes are rare.

The reason for this is as follows: if we wanted to perform Cache maintenance continuously, we would need to create a thread, and its operations would be competing with user operations for shared locks. Additionally, some environments restrict the creation of threads, which would make CacheBuilder unusable in that environment.

Instead, we put the choice in your hands. If your cache is high-throughput, then you don't have to worry about performing cache maintenance to clean up expired entries and the like. If your cache does writes only rarely and you don't want cleanup to block cache reads, you may wish to create your own maintenance thread that calls Cache.cleanUp() at regular intervals.

If you want to schedule regular cache maintenance for a cache which only rarely has writes, just schedule the maintenance using ScheduledExecutorService.

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • 1
    just copy from the doc, not impressed – Simon Guo Sep 30 '16 at 14:46
  • 78
    @SimonGuo I wrote much of the doc. – Louis Wasserman Sep 30 '16 at 15:32
  • @LouisWasserman : I have a question. If I use expireAfterAccess and suppose my entry gets expired after 2 hours. Now if I call get() for that entry after some time (say 5 hours), will it get cached again? or will it expire for good? – Boola Jan 31 '17 at 11:21
  • 3
    @Boola it will get cached again for another two hours. – Louis Wasserman Jan 31 '17 at 17:32
  • @LouisWasserman: what is the point of expireAfterAccess if it gets cached again even after 5 hours? I am not clear. Could you please clarify – firstpostcommenter Jan 25 '19 at 15:46
  • 3
    I think the miscommunication here is will there be another cache-load. Once the entry has expired a call to get will cause the entry to be reloaded and then cached again. – troutinator Jun 07 '19 at 20:07
  • yes in this case there will be another load call which will be cached again – Sumit Kumar Saha Oct 24 '20 at 12:04
  • can i get more specifics on "occasional cache accesses" aspects of removal. I have a cache that has a very high amount of reads for other keys, but the key that is not being called that should be getting removed is not being removed even with a TTL of 10 minutes – SnG Feb 13 '21 at 17:48