我想创建一个LinkedHashMap,它将根据可用内存限制其大小(即freeMemory + (maxMemory - allocatedMemory)
低于某个阈值时)。这将用作一种缓存形式,可能使用“最近最少使用”作为缓存策略。
我担心的是,allocateMemory还包括(我假设)非垃圾收集数据,因此会高估估计已用内存的数量。我担心这可能会产生意想不到的后果。
例如,LinkedHashMap可能会继续删除项目,因为它认为没有足够的可用内存,但可用内存不会增加,因为这些已删除的项目不会立即被垃圾回收。
有没有人对这类事有经验?我的顾虑值得关注吗?如果是这样,有人可以建议一个好方法吗?
我应该补充一点,我也希望能够“锁定”缓存,基本上说“好了,从现在开始不要因为内存使用问题而删除任何内容”。
答案 0 :(得分:1)
我知道我有偏见,但我真的必须强烈推荐我们的MapMaker。使用softKeys()或softValues()功能,具体取决于它是否为密钥的GC集合,或者是否可以清理条目时更恰当地描述的值。
答案 1 :(得分:0)
缓存往往存在问题。 IIRC,Sun的JRE中有一个SoftCache
,它遇到了很多问题。
无论如何,最简单的方法是在地图中使用SoftReference
。只要SoftReference
加Map.Entry
的开销明显低于缓存数据,这应该可以正常工作。
或者,您可以像WeakHashMap
一样使用ReferenceQueue
并轮询它或在其上有一个线程阻塞(不幸的是,每个实例一个线程)。小心同步问题。
“锁定”地图,您可能希望在必要时避免使用。您需要保留对所有数据的强引用(如果不为null则逐出)。那将是丑陋的。
答案 2 :(得分:0)
我强烈建议使用像Ehcache这样的东西,而不是重新发明一个缓存系统。它使用起来非常简单,非常易于配置,效果很好。
答案 3 :(得分:0)
正如matt b所说,像Ehcache或JbossCache这样的东西是很好的第一步。
如果你想要轻量级和正在处理的东西,请查看谷歌收藏。例如,您可以使用MapMaker(http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/BiMap.html)创建具有Soft / Weak键和值的映射,因此它只会缓存它有空间的项目(尽管您不会获得LRU)。
答案 4 :(得分:0)
我过去也有同样的需求,这就是我实现缓存的方式:
我打算在缓存上添加一个额外的防护,以便在出现比基于内存的驱逐更快的情况下进行驱逐,但直到现在我才发现需要这样做。