番石榴缓存' expireAfterWrite'似乎并不总是奏效

时间:2014-09-24 21:31:07

标签: caching guava

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

我希望在10分钟内未发送到客户端的响应对象已过期并自动从缓存中删除,但我注意到即使在10,15,20分钟后,Response对象也不会总是过期。它们会在大量填充缓存时到期,但是当系统变为空闲时,就像最后500个响应对象一样,它会停止删除这些对象。 有人可以帮助理解这种行为吗?谢谢

1 个答案:

答案 0 :(得分:22)

这在文档中指定:

  

如果请求expireAfterWrite或expireAfterAccess,则可能会在每次缓存修改,偶尔的缓存访问或对Cache.cleanUp()的调用时逐出条目。过期的条目可能由Cache.size()计数,但读取或写入操作永远不可见。

维基上有更详细的内容:

  

使用CacheBuilder构建的缓存不会“自动”执行清理和逐出值,或者在值到期后立即执行或逐出任何类型。相反,它在写入操作期间执行少量维护,或者在写入很少的情况下偶尔执行读取操作。

     

原因如下:如果我们想执行Cache   维护不断,我们需要创建一个线程,它的   操作将与共享锁的用户操作竞争。   此外,某些环境限制线程的创建,   这将使CacheBuilder在该环境中无法使用。

     

相反,我们将选择权交给您。如果您的缓存是   高吞吐量,那么你不必担心执行缓存   维护以清理过期的条目等。如果你的缓存   写入很少,你不希望清理阻止缓存   读取,您可能希望创建自己的调用维护线程   Cache.cleanUp()定期。

     

如果要为缓存安排常规缓存维护   只有很少写入,只需使用安排维护   ScheduledExecutorService的。