固定大小LinkedHashMap内存泄漏?

时间:2013-10-28 11:16:35

标签: java caching memory-leaks linkedhashmap

我正在尝试使用LinkedHashMap作为本地FIFO缓存解决方案,覆盖其removeEldestEntry方法以保持大小固定:

Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, .75F, false) {
   protected boolean removeEldestEntry(Map.Entry eldest) {
      return size() > MAX_CACHE_SIZE;
   }
};

但是当我不断向地图监控进程内存添加新条目时,我发现它一直在增长,直到使用最大虚拟机内存,但地图大小不会增加。

是否按设计?如果丢弃旧值并且地图的大小有限,为什么需要更多内存呢?

更新: 根据要求,我附上完整的代码:

@Test
public void mapMemory() {
    final int MAX_CACHE_SIZE = (int) 1E3;
    Map lhm = new LinkedHashMap(MAX_CACHE_SIZE + 1, 1F, false) {
       protected boolean removeEldestEntry(Map.Entry eldest) {
          return size() > MAX_CACHE_SIZE;
       }
    };

    for (long i = 0; i < 1E10; i++) {
        lhm.put("key_" + i, "VALUE");
    }
}

3 个答案:

答案 0 :(得分:2)

在多线程上下文中解释LinkedHashMap的内存泄漏问题的博客文章

https://hoangx281283.wordpress.com/2012/11/18/wrong-use-of-linkedhashmap-causes-memory-leak/

答案 1 :(得分:0)

构造函数中的第二个参数定义了loadFactor,乘以第一个参数(地图大小),它会为您提供触发调整大小的值(大小)。所以在你的情况下你应该(可能)使用loadFactor = 1。

编辑:
您的内存泄漏是由您未向我们展示的内容引起的,您上面的代码绝不会导致内存泄漏 检查您可能保留对旧值/对象的引用的位置。映射本身不会导致内存泄漏 - 如果它确实所有使用映射的系统(并且有很多它们)将每隔几个小时崩溃。

答案 2 :(得分:0)

如果您需要随机访问集合的内容,那么它实际上不是FIFO。

应该注意的是,集合不存储对象,它们存储对象的引用,这是一个重要的区别。将相同的对象存储在2个不同的集合中将不会产生大量的内存开销,因此最好的解决方案是将相同的对象存储到队列和映射中,当需要FIFO行为时使用队列,当需要随机访问时使用Map 。

您必须记住在完成它时从两个集合中删除该对象,否则它将不会是GC。