使用.clear()或让GC处理它

时间:2011-04-09 04:26:58

标签: java garbage-collection hashmap clear

在我的代码的一部分中,创建了两个LinkedHashMaps,如下所示:

Map<Byte, Integer> hash1 = new LinkedHashMap<Byte, Integer>();
Map<Byte, Integer> hash2 = new LinkedHashMap<Byte, Integer>();

之后,运行for循环将值添加到各自的HashMap中,然后HashMaps运行另一个用于创建数据包的循环。调用第二个循环后调用.clear()会不会更好?或者让垃圾收集器处理它?<​​/ p>

2 个答案:

答案 0 :(得分:8)

如果不调用clear(),GC将不会处理它,因为对象仍然会被hashmap引用,直到它超出范围。

如果hashmap无论如何都超出了范围,你可以让GC处理它。首先清除它可能不会产生可衡量的差异。

答案 1 :(得分:1)

从垃圾收集的角度来看,在这些地图上调用clear()可能会浪费大量时间。

有三种情况需要考虑:

  • 如果包含(仅)HashMap引用的变量即将超出范围,则在其上调用clear()是浪费时间。即使为变量分配null也是(微不足道)浪费时间。

    下次在包含它们的堆上运行GC时,将收集HashMap个对象。调用clear()不会更快地发生这种情况,也不会减少GC所做的工作。

  • 如果变量不会超出范围,但您不会重复使用HashMaps,那么为{em>>分配null可能会制作HashMaps可以更快地获得GC的资格,但是JVM 可能会处理这个案例。如上所述,拨打clear()是浪费时间。

  • 如果变量不在范围之外,并且您要重用HashMaps,那么清除它们可能是正确的做法。但是,调用clear()的真正目的是摆脱可能会减慢哈希表操作的旧(并且可能是不需要的)映射条目,这可能导致不正确的结果。

(这是关于@ squacknull答案的评论的详细说明。)


要理解调用clear无法帮助GC的原因,您需要了解HotSpot收集器的工作原理。 HotSpot收藏家正在“复制”从“从”空间复制到“到”空间的收藏家。通过递归跟踪“from”空间中的可到达对象并将它们复制到“to”空间来完成工作。然后,检查任何剩余的对象以查看它们是否需要最终确定,并且可递归地跟踪可最终化的对象并将其复制到“到”空间。最后,“from”空间归零,GC完成。 (当你考虑世代,同时收藏家等等时,它比这更复杂,但不能去那里......)

假设HashMap无法访问且无法终结,那么标记它的任何阶段都不会找到它,它的内部对象(即哈希数组或链)或地图中的键和值...假设后者其他路线无法到达。因此,清除散列数组(这是clear()所做的)只是清除了无论如何都不会被跟踪的对象的元素。它对GC必须做的事情没有影响。