如何使用可用RAM有效地在Java中缓存对象?

san*_*ity 25 java caching soft-references guava

我需要使用一定比例的可用RAM来缓存Java中的对象.我知道其他人已经提出了这个问题,但没有一个回复符合我的要求.

我的要求是:

  • 简单轻巧
  • 并不比普通的HashMap慢得多
  • 使用LRU或一些近似LRU的删除策略

我尝试使用LinkedHashMap,但是它要求你指定最大数量的元素,我不知道填充可用RAM需要多少元素(它们的大小会有很大差异).

我目前的方法是使用Google Collection的MapMaker,如下所示:

Map<String, Object> cache = new MapMaker().softKeys().makeMap();
Run Code Online (Sandbox Code Playgroud)

这看起来很有吸引力,因为它应该在需要更多RAM时自动删除元素,但是存在一个严重的问题:它的行为是填满所有可用的RAM,此时GC开始抖动,整个应用程序的性能急剧恶化.

我听说过像EHCache这样的东西,但它对于我需要的东西似乎相当重,而且我不确定它是否足够快我的应用程序(记住解决方案不能比HashMap慢得多) .

小智 7

我对你有类似的要求 - 并发(在2个hexacore CPU上)和LRU或类似的 - 并且还尝试了Guava MapMaker.我发现softValues()比weakValues()慢得多,但是当内存填满时,两者都让我的应用程序变得非常缓慢.

我尝试了WeakHashMap并且问题较少,奇怪甚至比使用LinkedHashMap作为LRU缓存通过其removeEldestEntry()方法更快.

但对我来说最快的是ConcurrentLinkedHashMap,它使我的应用程序比我试过的任何其他缓存快3-4(!!)倍.经过几天的挫折之后,欢乐!它显然被整合到了Guava的MapMaker中,但LRU功能无论如何都不在Guava的r07中.希望对你有效.