gpt4 book ai didi

java - 可靠地强制驱逐 Guava map

转载 作者:IT老高 更新时间:2023-10-28 21:00:42 26 4
gpt4 key购买 nike

编辑:我已经重新组织了这个问题,以反射(reflect)自此以来可用的新信息。

该问题基于Viliam对有关Guava Maps使用懒惰驱逐的问题的回答:Laziness of eviction in Guava's maps

请先阅读此问题及其答案,但从本质上来说,结论是 Guava map 不会异步计算和执行驱逐。给出以下 map :

ConcurrentMap<String, MyObject> cache = new MapMaker()
.expireAfterAccess(10, TimeUnit.MINUTES)
.makeMap();

进入条目后经过十分钟后,直到再次“触摸” map 后,该条目仍不会退出。执行此操作的已知方法包括常用的访问器- get()put()containsKey()

我的问题的第一部分[已解决]:还有哪些其他调用导致 map 被“触摸”?具体来说,有人知道 size()是否属于此类?

对此感到疑惑的原因是,我已经实现了一个计划任务,偶尔会使用以下简单方法微调用于缓存的Guava映射:
public static void nudgeEviction() {
cache.containsKey("");
}

但是,我也使用 cache.size()以编程方式报告 map 中包含的对象数量,以确认此策略是否有效。但是我从这些报告中看不到任何区别,现在我想知道 size()是否还会导致驱逐。

答案:因此,Mark指出,在版本9中,驱逐仅由 get()put()replace()方法调用,这将解释为什么我看不到 containsKey()的影响。这显然会随着即将发布的下一版 Guava 而改变,但是不幸的是我的项目的发布会更快。

这使我陷入一个有趣的困境。通常,我仍然可以通过调用 get("")来触摸 map ,但实际上我正在使用计算 map :
ConcurrentMap<String, MyObject> cache = new MapMaker()
.expireAfterAccess(10, TimeUnit.MINUTES)
.makeComputingMap(loadFunction);

其中 loadFunction从数据库中加载与 key 对应的 MyObject。直到r10为止,我似乎都没有简单的强制驱逐的方法。但是,我的问题的第二部分甚至质疑了是否能够可靠地强制驱逐:

我的问题的第二部分[已解决]:作为响应 to one of the responses to the linked question,触摸 map 是否可靠地将所有过期的条目逐出?在链接的答案中, Niraj Tolia表示相反的意思,说逐出可能仅是分批处理,这意味着可能需要多次调用触摸 map 才能确保逐出所有过期的对象。他没有详细说明,但是这似乎与根据并发级别将 map 分为多个部分有关。假设我使用的是r10,其中 containsKey("")确实会调用逐出,那么它将用于整个 map 还是仅用于其中一个分段?

回答: maaartinus已经解决了问题的这一部分:

Beware that containsKey and other reading methods only run postReadCleanup, which does nothing but on each 64th invocation (see DRAIN_THRESHOLD). Moreover, it looks like all cleanup methods work with single Segment only.



因此,即使在r10中,调用 containsKey("")似乎也不可行。这将我的问题简化为标题:如何可靠地强制驱逐发生?

注意:我的Web应用程序受此问题影响的部分原因是,当我实现缓存时,我决定使用多个映射-每个数据对象类一个。因此,有了这个问题,就有可能执行一个代码区域,从而导致一堆 Foo对象被缓存,然后 Foo缓存长时间不被再次触摸,因此它不会退出任何东西。同时 BarBaz对象正在从其他代码区域中缓存,并且正在消耗内存。我在这些 map 上设置了最大尺寸,但这充其量只是一种脆弱的保护措施(我假设其效果是立竿见影的-仍然需要确认)。

更新1:感谢Darren提出了相关问题的链接-他们现在拥有我的投票权。因此,看起来分辨率正在酝酿之中,但似乎不太可能出现在r10中。同时,我的问题仍然存在。

更新2:此时,我只是在等待Guava团队成员提供有关hack maaartinus的反馈,我将它们放在一起(请参阅下面的答案)。

最新更新:收到反馈!

最佳答案

我刚刚将方法Cache.cleanUp()添加到了 Guava 。从MapMaker迁移到CacheBuilder后,您可以使用它强制驱逐。

关于java - 可靠地强制驱逐 Guava map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7069290/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com