【发布时间】:2013-07-12 14:00:15
【问题描述】:
我有一个包含十万个条目的新旧地图:
Map<State, CostAndIndex> oldMap = new LinkedHashMap<State, CostAndIndex>();
Map<State, CostAndIndex> newMap = new LinkedHashMap<State, CostAndIndex>();
在循环的每次迭代结束时,我只是这样做:
oldMap = newMap;
使用这种方法,我在一段时间后内存不足,即使在调用 System.gc(); 时也是如此。重新分配后。
然后我在重新分配之前添加了一个清除,我不再耗尽内存。
oldMap.clear();
oldMap = newMap;
我的问题:为什么它会改变什么?指针重新分配不是告诉 Java 不再需要地图及其内容,并且它可以清除数据并出于任何目的重用空间吗?
注意:这是运行 Java HotSpot 1.7。在 Java HotSpot 1.6 中,我用第一种方法更快地耗尽了内存,我也不清楚这是为什么。
【问题讨论】:
-
不清楚您的代码到底是什么样的。如果您只曾经在循环之前初始化
newMap,那么您只会得到一张可能会越来越大的地图。一个简短但完整的程序来演示这个问题会更容易解释...... -
在对
map.clear()的调用结束时,地图的内容将超出范围,无法访问并受 GC。然而,在重新分配期间,oldMap仍然是范围可访问的(尽管没有对它的引用),并且直到for循环结束之后才能进行 GC(我相信)。但是,鉴于@JonSkeet 在这里,我将继续前进并退出。 -
@ColinMorelli 请参阅我在答案中对我犯的愚蠢错误的评论。但是,我不清楚您的“oldMap 仍然是范围可访问的(尽管没有对它的引用),并且在 for 循环结束之前无法进行 GC”。你能扩展一下吗?
标签: java memory-management garbage-collection