可靠地迫使番石榴地图被驱逐 [英] reliably forcing Guava map eviction to take place

查看:108
本文介绍了可靠地迫使番石榴地图被驱逐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:我重新组织了这个问题,以反映自上市以来的新信息。

I've reorganized this question to reflect the new information that since became available.

此问题基于回复关于Guava Maps使用懒惰驱逐的 Viliam 提出的问题:在Guava地图中驱逐的懒惰

This question is based on the responses to a question by Viliam concerning Guava Maps' use of lazy eviction: Laziness of eviction in Guava's maps

请阅读此问题及其回复首先,但基本上结论是,番石榴地图不会异步计算和强制驱逐。给出以下映射:

Please read this question and its response first, but essentially the conclusion is that Guava maps do not asynchronously calculate and enforce eviction. Given the following map:

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

访问一个条目后十分钟过后,在地图出现之前,它仍然不会被驱逐再次感动。已知的方法包括通常的访问者 - get() put() containsKey()

Once ten minutes has passed following access to an entry, it will still not be evicted until the map is "touched" again. Known ways to do this include the usual accessors - get() and put() and containsKey().

问题的第一部分[已解决]:其他调用会导致地图显示被感动?具体来说,有没有人知道 size()是否属于这个类别?

The first part of my question [solved]: what other calls cause the map to be "touched"? Specifically, does anyone know if size() falls into this category?

想知道这个的原因是我已经实现了一个计划任务,偶尔轻推我用于缓存的Guava地图,使用这个简单的方法:

The reason for wondering this is that I've implemented a scheduled task to occasionally nudge the Guava map I'm using for caching, using this simple method:

public static void nudgeEviction() {
    cache.containsKey("");
}

但我也使用 cache.size( )以编程方式报告地图中包含的对象数量,以确认此策略是否有效。但我无法看到这些报告的差异,现在我想知道 size()是否也会导致驱逐。

However I'm also using cache.size() to programmatically report the number of objects contained in the map, as a way to confirm this strategy is working. But I haven't been able to see a difference from these reports, and now I'm wondering if size() also causes eviction to take place.

答案:因此Mark指出,在第9版中,驱逐只能由 get(), put() replace()方法,这可以解释为什么我没有看到效果的containsKey()。这显然会随着即将发布的下一版番石榴而改变,但遗憾的是我的项目发布时间很快。

Answer: So Mark has pointed out that in release 9, eviction is invoked only by the get(), put(), and replace() methods, which would explain why I wasn't seeing an effect for containsKey(). This will apparently change with the next version of guava which is set for release soon, but unfortunately my project's release is set sooner.

这让我陷入了一个有趣的困境。通常我仍然可以通过调用 get()来触摸地图,但我实际上是在使用计算地图:

This puts me in an interesting predicament. Normally I could still touch the map by calling get(""), but I'm actually using a computing map:

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

其中 loadFunction 加载 MyObject 对应于数据库中的密钥。它开始看起来像我没有简单的方法强迫驱逐直到r10。但是,即使能够可靠地强制驱逐,我的问题的第二部分也会产生疑问:

where loadFunction loads the MyObject corresponding to the key from a database. It's starting to look like I have no easy way of forcing eviction until r10. But even being able to reliably force eviction is put into doubt by the second part of my question:

我的问题的第二部分[已解决]:作出反应对链接问题的回复之一,是否触摸地图可靠地逐出所有过期的条目?在链接的答案中, Niraj Tolia 另有说明,称驱逐可能只是分批处理,这意味着多次通话可能需要触摸地图以确保所有过期的对象被驱逐。他没有详细说明,但这似乎与基于并发级别的地图被拆分成相关。假设我使用了r10,其中 containsKey()会调用驱逐,那么这是针对整个地图,还是只针对其中一个片段?

The second part of my question [solved]: In reaction to one of the responses to the linked question, does touching the map reliably evict all expired entries? In the linked answer, Niraj Tolia indicates otherwise, saying eviction is potentially only processed in batches, which would mean multiple calls to touch the map might be needed to ensure all expired objects were evicted. He did not elaborate, however this seems related to the map being split into segments based on concurrency level. Assuming I used r10, in which a containsKey("") does invoke eviction, would this then be for the entire map, or only for one of the segments?

答案: maaartinus解决了这部分问题:

Answer: maaartinus has addressed this part of the question:


注意 containsKey 和其他阅读方法只运行 postReadCleanup ,除了每次第64次调用外什么都不做(参见DRAIN_THRESHOLD) )。此外,看起来所有清理方法仅适用于单个Segment。

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.

所以它看起来像调用 containsKey(即使在r10中,)也不是可行的修复方法。这减少了我对标题的质疑:如何可靠地强制驱逐?

So it looks like calling containsKey("") wouldn't be a viable fix, even in r10. This reduces my question to the title: How can I reliably force eviction to occur?

注意:部分我的Web应用程序明显受此问题影响的原因是,当我实现缓存时,我决定使用多个映射 - 每个映射一个数据对象。所以有了这个问题,就有可能执行一个代码区域,导致一堆 Foo 对象被缓存,然后 Foo 长时间不再触摸缓存,因此它不会驱逐任何东西。同时 Bar Baz 对象正在从其他代码区域缓存,并且内存正在被吃掉。我在这些地图上设置了最大尺寸,但这最好是一个脆弱的保护措施(我假设其效果是立竿见影的 - 仍然需要确认这一点)。

Note: Part of the reason my web app is noticeably affected by this issue is that when I implemented caching I decided to use multiple maps - one for each class of my data objects. So with this issue there is the possibility that one area of code is executed, causing a bunch of Foo objects to be cached, and then the Foo cache isn't touched again for a long time so it doesn't evict anything. Meanwhile Bar and Baz objects are being cached from other areas of code, and memory is being eaten. I'm setting a maximum size on these maps, but this is a flimsy safeguard at best (I'm assuming its effect is immediate - still need to confirm this).

更新1:感谢Darren链接相关问题 - 他们现在有了我的选票。所以它看起来像是一个解决方案,但似乎不太可能在r10中。与此同时,我的问题仍然存在。

UPDATE 1: Thanks to Darren for linking the relevant issues - they now have my votes. So it looks like a resolution is in the pipeline, but seems unlikely to be in r10. In the meantime, my question remains.

更新2:此时我只是在等待番石榴团队成员提供反馈意见hack maaartinus和我放在一起(见下面的答案)。

UPDATE 2: At this point I'm just waiting for a Guava team member to give feedback on the hack maaartinus and I put together (see answers below).

最后更新:收到反馈!

推荐答案

我刚刚将方法 Cache.cleanUp()添加到番石榴。从 MapMaker 迁移到 CacheBuilder 后,您可以使用它来强行驱逐。

I just added the method Cache.cleanUp() to Guava. Once you migrate from MapMaker to CacheBuilder you can use that to force eviction.

这篇关于可靠地迫使番石榴地图被驱逐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆