【问题标题】:Using .clear() or letting the GC take care of it使用 .clear() 或让 GC 处理它
【发布时间】:2011-04-09 04:26:57
【问题描述】:

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

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

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

【问题讨论】:

  • 第二次循环后哈希映射是否超出范围?因为只要它们在作用域内,仍然有对其元素的引用,GC 不会处理它们。

标签: java hashmap garbage-collection


【解决方案1】:

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

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

【讨论】:

  • 我应该提到这两个 HashMap 是在一个函数中创建的,并且不会在任何时候返回。它们的范围在该功能本身之内。
  • @PuppyKevin,然后清除它们或对它们的引用将完全浪费您的时间,并且对性能没有任何影响。
  • 如果是这样的话,那么正如我上面建议的那样,确实可能没有太大区别。理论上(我在理论上强调),如果根本没有对 hashmap 成员的引用(即使不再引用 hashmap 本身),您可能会使 GC 过程的标记阶段更简单一些。实际上,您可能永远不会注意到差异。如果您非常担心内存开销,请尝试为每个函数重用一个字节缓冲区,而不是每次都创建新对象。不过,这可能是过早的优化。
  • 事实上,在 hashmap 超出范围之前清除它会降低性能,因为执行 clear() 的时间非常少,因为 GC 将收集所有涉及的对象,而无需擦除哈希图参考。
  • 好的,谢谢大家。我曾认为使用 .clear() 不会帮助我提高性能,但我只是想确定一下。
【解决方案2】:

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

需要考虑三种情况:

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

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

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

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

(这是对 @squacknull 答案的 cmets 的详细说明。)


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

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

【讨论】:

    猜你喜欢
    • 2012-10-01
    • 2014-10-16
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 2019-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多