咖啡因:如何确定适当的缓存大小

6
我有一个计算密集型的离线处理任务,需要几个小时才能运行完。我正在使用Caffeine作为我的内存缓存。如何设置最大缓存大小是一个好的启发式方法?我使用8GB的RAM运行我的Java程序,并愿意给缓存约4GB的内存,但我不确定内存如何转换为缓存实际大小。我决定采用.softValues()让JVM来决定,但在Caffeine的JavaDoc中遇到了以下警告:

警告:在大多数情况下,最好设置每个缓存的最大大小,而不是使用软引用。只有在您熟悉软引用的实际后果时,才应使用此方法。

2个回答

14

软引用在概念上很有吸引力,但在长时间运行的JVM中通常会影响性能。这是因为它们通过填充老年代而创建堆压力,并且只有在进行完整GC时才会被回收。这可能导致GC抖动,每次释放足够的内存后,内存很快就被消耗完,需要进行另一次完整GC。对于延迟敏感的应用程序,由于驱逐是全局的,因此进一步受到影响,因为没有办法提示哪些缓存最关键。

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

不幸的是,大小调整的最佳答案是猜测、测量和重复。导出统计数据,尝试一种设置,并适当调整。命中率曲线可以通过捕获访问跟踪(键哈希的日志)并使用不同的大小进行模拟来获得。这是有趣的数据,但通常进行几个简单的运行以进行调整就足够了。


3
软引用允许虚拟机在内存不足时回收对象。这与缓存是一种不同的策略。你可以简单地使用WeakHashMap(但是SoftReference和WeakReference之间有区别)。
一个重要的区别是,缓存通常让你决定驱逐对象的策略(lru、fifo等),而软/弱引用不会。
你应该能够至少大致猜测一个对象的大小。它是1k、1mb还是10mb?
如果你真的不知道你的对象有多大,大多数缓存都允许你添加一个监听器来驱逐并记录它。再加上查找时缓存未命中的日志,就可以很好地了解缓存的性能。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接