【问题标题】:Guava cache 'expireAfterWrite' does not seem to always work番石榴缓存“expireAfterWrite”似乎并不总是有效
【发布时间】:2014-09-24 21:31:06
【问题描述】:
private Cache<Long, Response> responseCache = CacheBuilder.newBuilder()
            .maximumSize(10000)
            .expireAfterWrite(10, TimeUnit.MINUTES)
            .build();

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

【问题讨论】:

标签: caching guava


【解决方案1】:

这是在文档中指定的:

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

还有更多关于 wiki 的详细信息:

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

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

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

如果您想为某个缓存安排定期缓存维护, 很少有写入,只需安排维护使用 ScheduledExecutorService。

【讨论】:

  • 只是从文档中复制,没有留下深刻印象
  • @SimonGuo 我写了很多文档。
  • @LouisWasserman:我有一个问题。如果我使用 expireAfterAccess 并假设我的条目在 2 小时后过期。现在,如果我在一段时间后(比如 5 小时)为该条目调用 get(),它会再次被缓存吗?还是会永久过期?
  • @Boola 它将再次被缓存两个小时。
  • 我认为这里的误解是会有另一个缓存加载。一旦条目过期,调用 get 将导致条目重新加载,然后再次缓存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多