当前位置: 首页 > 面试题库 >

可靠地强迫驱逐番石榴地图

尤博达
2023-03-14
问题内容

编辑: 我已经重新组织了这个问题,以反映自从可用以来的新信息。

请先阅读此问题及其答案,但基本上得出的结论是,番石榴图不会异步计算和执行驱逐。给出以下地图:

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

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

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

对此感到疑惑的原因是,我已经实现了一个计划任务,偶尔会使用以下简单方法微调用于缓存的Guava映射:

html" target="_blank">public static void nudgeEviction() {
    cache.containsKey("");
}

但是,我还用于cache.size()以编程方式报告地图中包含的对象数量,以确认此策略是否有效。但是我从这些报告中看不出有什么不同,现在我想知道是否size()还会导致驱逐事件发生。

答:
所以马克指出,在第9版,驱逐仅被调用get()put()replace()方法,这可以解释为什么我没有看到一个效果containsKey()。这显然会随着即将发布的下一版guava改变,但是不幸的是我的项目的发布会更快。

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

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

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

我的问题的第二部分[解决]:
在反应的反应之一链接的问题,并触摸地图可靠地逐出所有过期项?在链接的答案中,NirajTolia表示不同意,说逐出可能仅是分批处理,这意味着可能需要多次触摸地图,以确保逐出所有过期的物体。他没有详细说明,但是这似乎与根据并发级别将地图分为多个部分有关。假设我使用的是r10(其中acontainsKey("")确实调用了逐出),那么它将用于整个地图还是仅用于其中一个细分市场?

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

请注意,containsKey其他读取方法仅运行postReadCleanup,仅在第64次调用时才执行任何操作(请参阅DRAIN_THRESHOLD)。而且,看起来所有清除方法仅适用于单个Segment。

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

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

更新1: 感谢达伦(Darren)将相关问题联系在一起-
他们现在有我的票。因此,看起来分辨率正在酝酿之中,但似乎不太可能出现在r10中。同时,我的问题仍然存在。

更新2: 在这一点上,我只是在等待番石榴团队的成员提供有关黑客maaartinus的反馈,我将它们放在一起(请参阅下面的答案)。

最后更新: 收到反馈!


问题答案:

我刚刚将方法添加Cache.cleanUp()到了番石榴。从迁移到后MapMakerCacheBuilder您可以使用它强制驱逐。



 类似资料:
  • 问题内容: 我有一个的关键无非是像“123”等我得到的数值,因为这个数值是从UI在我的JSF组件来数值。我不想更改UI组件的合同。 现在,我想基于上面创建一个,我在类中看到了一些方法,但是所有方法都集中在转换值而不是键上。 有没有更好的转换方法? 问题答案: Java 8的更新 您可以使用流来执行此操作: 假定所有键都是s的有效字符串表示形式。另外,转换时可能会发生冲突;例如,与两个地图。 我认为

  • 问题内容: 刚刚发现了Guava库项目。 这些与GWT兼容吗? 问题答案: 从该页面的介绍性PDF中, 您可以在…上使用这些库。 在JDK 6上 在Android上, 我们认为。需要志愿者来帮助我们进行测试。 在Google App Engine上, 我们认为。需要志愿者来帮助我们进行测试。 在GWT上-参差不齐! 由于GWT的JDK库支持 可能参差不齐,也许是2/3,所以到目前为止,这些库中的东

  • 问题内容: 我想知道哪个更有效,为什么? 1) 要么 2) 问题答案: 我看不出您为什么要在此处使用builder的任何原因: 比在这种情况下制作一个更具可读性, 不会推断通用类型,并且在用作单行代码时必须自己指定类型, (来自docs) 在与另一个不可变集合调用时 做得很好( 尝试避免在安全的情况下实际复制数据 ), (从源) 调用以前创建的,同时避免为零元素和一元素集合创建任何列表(分别返回空

  • 我想为番石榴设个坑(http://pitest.org/)进行突变熟练度测试,但我在尝试运行时出现以下错误。这是我得到的错误: 基本上,要么PIT没有检测到测试,要么测试在PIT中运行不正常,所有测试都失败了。我读了这篇文章:JUnit测试通过,但PIT说套件不是绿色的,我认为“您的代码库是否包含可变静态状态?(例如在单例中)”是问题所在,但我不知道如何修复它。如果测试套件有一些隐藏的顺序依赖关系

  • 我的 Spark 版本是 2.2.0,它在本地工作,但在具有相同版本的 EMR 上,它给出了以下异常。

  • 问题内容: 我已经使用番石榴已有一段时间了,并且对此感到非常信任,直到昨天我偶然发现了一个例子,这让我开始思考。长话短说,这里是: 运行此命令后,您可以看到 ImmutableList 内部的条目的值已更改。如果此处涉及两个线程,则一个线程可能碰巧看不到另一个线程的更新。 同样令我非常不耐烦的是,Effective Java中的Item15,第5点说: 在构造函数中制作防御程序副本 -看起来很合理