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



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

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

之后,运行for循环将值添加到各自的HashMap中,然后通过另一个用于创建数据包的循环运行HashMap。在调用第二个循环后调用.clear((更好,还是让垃圾收集器来处理它更好?

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

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

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

有三种情况需要考虑:

  • 如果包含(仅(HashMap引用的变量即将超出范围,那么对它们调用clear()是浪费时间。即使将null分配给变量也是(微小的(时间浪费。

    下次GC在包含HashMap对象的堆上运行时,将收集这些对象。调用clear()不会加快实现速度,也不会减少GC所做的工作。

  • 如果变量不会超出范围,但您不会重用HashMaps,那么将null分配给它们可能会使HashMaps更快地符合GC条件,但JVM无论如何都可能处理这种情况。如上所述,调用clear()是浪费时间。

  • 如果变量没有超出范围,并且您将重用HashMaps,那么清除它们可能是正确的做法。然而,调用clear()的真正目的是清除旧的(可能是不需要的(映射条目,这些条目可能会减慢哈希表操作的速度,并可能导致不正确的结果。

(这是对@squarcknull回答的评论的详细阐述。(


要理解为什么调用clear对GC没有帮助,您需要了解HotSpot收集器是如何工作的。HotSpot收集器是从"from"空间复制到"to"空间的"复制"收集器。这项工作是通过递归地跟踪"from"空间中的可访问对象并将它们复制到"to"空间来完成的。然后,检查所有剩余的对象,看看它们是否需要最终确定,并递归地跟踪可最终确定的对象并将其复制到"到"空间。最后,"from"空间为零,GC完成。(比这更复杂的是,当你考虑代、并发收集器等等时,但不要去那里…(

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

最新更新