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

Mar*_*234 13 caching guava

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

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

Lou*_*man 23

这在文档中指定:

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

维基上有更多细节:

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

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

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

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

  • @SimonGuo我写了很多文档. (33认同)
  • @Boola它将再次缓存两个小时. (3认同)
  • 我认为这里的误解是是否会有另一个缓存加载。一旦条目过期,对 get 的调用将导致重新加载条目,然后再次缓存。 (3认同)