如何制作理想的缓存。

时间:2014-05-13 12:07:58

标签: java caching

在应用程序中,我们使用具有最大大小约束的LRU(最近最少使用)缓存(并发HashMap实现)。我想知道我是否可以提高此缓存的性能。以下是我在网上找到的几个替代方案。

  • 使用Google Gauva池库。(因为我的实现使用LRU,我看不到gauva库的任何好处)
  • 如果我将对象包装为软引用并在LRU映射中存储为值(没有任何大小约束),我能看到任何好处吗? (这不是一种理想的缓存方式。在主要的gc运行之后,所有的软引用都将被垃圾收集。)
  • 如何使用混合池,它是LRU映射+软参考映射的组合。(想法是当从LRU映射中修剪对象时,它存储在软参考映射中。 通过这种方法,我们可以在缓存中拥有更多的对象。但这种方法可能是一个耗时的方法。)

还有其他方法可以改善缓存的性能吗?

1 个答案:

答案 0 :(得分:3)

首先,欢迎来到缓存实施者和改进者俱乐部!

不要使用LRU。有许多算法比LRU更好,现在是 同时超过10岁。首先阅读这些相关的研究论文:

在这些论文中,您还可以找到有关自适应缓存概念的更多基础论文。 (例如2Q,LRFU,LRU-k)。

翘曲对象:这取决于你想要达到的目标。实际上,您至少有三个额外的对象用于缓存条目:哈希表条目,弱引用对象,缓存条目对象。使用这种方法可以增加内存占用量 效率低,例如由于短期到期,你有很多GC废弃。

适应可用内存:如果要适应可用内存,最好在内存变低时逐出条目。通过这种方式,您可以驱逐很少使用的条目,而不是随机驱逐。但是,这种方法提供了更多的编码。具有自动资源控制功能的EHCache已实现了类似的功能。

如果您想为缓存使用更多内存但避免低堆条件,那么引用包装器是一种简单易用的方法,但就所有内存效率和访问时间而言,它并不是高性能。

测量它!它在很大程度上取决于使用场景,无论您是否获得了“性能提升”#34;或不。理想情况下,您需要了解并考虑访问模式,缓存的对象大小,到期约束和预期的并行性。我整理了一个基准套件,您可以在GitHub上找到cache2k benchmarks

但是,目前,这些基准测试只关注替代政策效率和访问时间。缺少内存开销和可能的并行性的比较。这将以某种方式添加半年范围。基准测试结果可在cache2k benchmark results页面上找到。

如果您对该主题感兴趣并在该领域进行一些研究,请考虑为cache2k做出贡献。我对更多的基准测试代码,或使用场景的描述以及访问模式的痕迹感到特别高兴,以优化和改进替换算法。