在我的代码的一部分中,创建了两个LinkedHashMaps,如下所示:
Map<Byte, Integer> hash1 = new LinkedHashMap<Byte, Integer>();
Map<Byte, Integer> hash2 = new LinkedHashMap<Byte, Integer>();
之后,运行for循环将值添加到各自的HashMap中,然后HashMaps运行另一个用于创建数据包的循环。调用第二个循环后调用.clear()会不会更好?或者让垃圾收集器处理它?</ p>
答案 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必须做的事情没有影响。