是否有任何 Java 缓存可以限制内存中缓存的内存使用量,而不仅仅是实例计数?

2022-09-04 22:57:27

我正在寻找一个简单的内存中(和进程内)缓存,用于查询数据的短期缓存(但短期含义超出请求/响应,即会话边界)。EhCache可能会起作用,但看起来它可能没有提供我需要的一件事:不是对缓存对象数量的限制,而是对缓存数据消耗的内存量的限制。

我知道,如果不进行序列化,很难弄清楚给定对象的确切内存使用情况(一般来说,由于它的缓慢性违背了我的使用目的,我想避免这种情况),而且我自己必须提供大小估计。

那么:有没有一个简单的开源java缓存,允许定义缓存对象的“权重”,以限制缓存的内容量?

编辑(2010年11月):值得一提的是,有一个名为Java CacheMate的新项目试图解决这个问题,以及其他一些改进想法(多级内存中进程内缓存)


答案 1

我同意Paul的观点,即这通常通过使用软引用缓存来解决,尽管它可能会比您喜欢的更早地逐出条目。通常可接受的解决方案是使用普通缓存,该缓存逐出到软缓存,并在可能的情况下恢复未命中的条目。这种受害者缓存方法效果很好,可以为您提供较低的门槛,但如果可用内存可用,则会获得额外的好处。

可以通过启用 Java 代理来确定内存大小,并且在使用 SizeOf 实用程序 (http://sourceforge.net/projects/sizeof) 时,使用起来非常简单。我仅将其用于调试目的,我建议在将其用于正常使用之前先对开销进行基准测试。

在我的缓存库中,我计划在实现核心算法后添加插入评估器的功能。这样,您可以将集合存储为值,但通过所有集合大小之和绑定缓存。我已经看到未绑定的集合,因为缓存中的值会导致OutOfMemoryExceptions,因此进行控制非常方便。

如果你真的需要这个,我建议不要这样做,我们可以增强我目前的实现来支持这一点。你可以给我发电子邮件,ben.manes-at-gmail.com。


答案 2

使用启用了LRU算法的简单LinkedHashMap,并将所有带有SoftReference的数据放入其中怎么样...例如 cache.out(key, new SoftReference(value)) ??

这会将缓存限制为可用内存量,但不会终止程序的其余部分,因为当有内存需求时,Java会删除软引用...不是全部..最古老的第一...通常。如果将引用队列添加到实现中,则还可以从映射中删除停滞条目(仅键,无值)。

这将使您免于计算条目的大小并跟踪总和。