咖啡因:如何得出合适的缓存大小

Caffeine: How to come up with an appropriate cache size

我有一个计算密集型的一次性离线处理任务,需要几个小时才能完成 运行,我使用 Caffeine 作为我的内存缓存。设置最大缓存大小的好的启发式方法是什么?我正在 运行 将我的 Java 程序与 8GB RAM 连接起来,我愿意为缓存提供大约 4GB 的内存,但我不确定内存 t运行 与我的缓存实际大小的关系整体。我决定使用 .softValues() 来让 JVM 决定,但我 运行 在 JavaCaffeine 文档中使用了以下单词:

Warning: in most circumstances it is better to set a per-cache maximum size instead of using soft references. You should only use this method if you are well familiar with the practical consequences of soft references.

软引用允许 VM 在内存不足时回收对象。这在某种程度上是与缓存不同的策略。您可以简单地使用 WeakHashMap(但是 SoftReferenceWeakReference 之间存在差异)

一个很大的区别是,缓存通常让您决定驱逐对象(lru、fifo 等)的策略,而 Soft/Weak 引用则不会。

你至少应该能猜出物体的大小。是 1k、1mb、10mb 吗?

如果您真的不知道您的对象有多大,大多数缓存都允许您添加一个侦听器以逐出并记录它。结合查找缓存未命中的日志,您应该可以很好地了解缓存的执行情况。

软引用在概念上很有吸引力,但通常会损害长 运行 JVM 的性能。这是因为它们通过填满老年代产生堆压力,并且在完整 GC 期间只有 collected。这可能会导致 GC 抖动,每次释放足够的内存时,它很快就会被消耗掉,并且需要另一次完整的 GC。对于延迟敏感的应用程序,这会受到进一步影响,因为逐出是全局的,因为无法暗示哪些缓存是最关键的。

软引用不应该是默认的,去攻略吧。这可能是吞吐量、非面向用户的任务的合理简化。但是当 GC 时间、延迟和可预测的性能很重要时,它可能很危险。

遗憾的是,选择尺码的最佳答案是猜测、测量和重复。导出统计数据,尝试设置并适当调整。命中率曲线可以通过捕获访问轨迹(密钥哈希的日志)和 simulating 不同大小的它来获得。它的数据很有趣,但通常进行一些简单的调整运行就足够了。