【发布时间】:2011-01-10 15:50:35
【问题描述】:
我需要使用可用 RAM 的一部分在 Java 中缓存对象。我知道其他人问过这个问题,但没有一个回答符合我的要求。
我的要求是:
- 简单轻便
- 并不比普通的 HashMap 慢很多
- 使用 LRU,或一些近似于 LRU 的删除策略
我尝试了 LinkedHashMap,但它要求您指定最大元素数,而且我不知道需要多少元素才能填满可用 RAM(它们的大小会有很大差异)。
我目前的做法是使用 Google Collection 的 MapMaker 如下:
Map<String, Object> cache = new MapMaker().softKeys().makeMap();
这看起来很有吸引力,因为它应该在需要更多 RAM 时自动删除元素,但是有一个严重的问题:它的行为是填满所有可用的 RAM,此时 GC 开始崩溃,整个应用程序的性能急剧下降.
我听说过 EHCache 之类的东西,但对于我需要的东西来说,它似乎很重,而且我不确定它对于我的应用程序是否足够快(请记住,该解决方案不能比HashMap)。
【问题讨论】:
-
你在缓存什么样的对象?我不太关心缓存的性能,考虑到一旦你在过期策略之后,你会比普通的 Map 产生更多的开销,而 EHCache 是一个开发良好的缓存库,它(我'我想在这里通过 Spring 进行配置)设置起来并不复杂,而且使用起来比地图简单。
-
对象的大小从大约 1kb 到大约 10kbs 不等。我担心性能,因为从缓存中检索对象是在 CPU 密集型进程的内部循环中。如果它很慢,它可能会将我的应用程序执行其操作所需的时间从几分钟增加到几小时。
-
使用 softKeys() 如果你使用 equals(),你不会得到一个命中,只有当你用引用相等查找对象时你才会得到一个命中。如果您需要 equals() 来进行缓存命中,请改用 softValues()。
标签: java caching guava soft-references