【问题标题】:What triggers a full garbage collection in Java?什么触发了 Java 中的完整垃圾回收?
【发布时间】:2012-03-21 17:30:07
【问题描述】:

我想知道在 Java 中触发 Full Garbage Collection 的确切情况是什么。

显而易见的是:

  • 老一代用完了
  • 烫发用完
  • 调用 System.gc()

其他导致full gc的情况呢?特别是:

  • 幸存者空间中没有足够的可用空间来从伊甸园复制对象。
  • 次要集合无法应对新对象的分配率(虽然不知道如何)。

我正在运行 Sun Java 1.6 并使用 Concurrent Mark-Sweep 和 ParNew for new gen。

【问题讨论】:

  • 正如 Chin Boon 所暗示的,这些“显而易见”的问题都不一定会导致完整的 GC,这完全取决于主动垃圾收集器算法的工作方式。特别是,据我了解,很多垃圾收集器或多或少地忽略了System.gc()。 (别忘了,GC 算法甚至可能没有“完整集合”的概念——这听起来可能有些牵强,但我还没有看到 G1 collector 在我们的应用程序上这样做。)
  • 你认为带有 G1 的 JVM 在堆空间用完时会做什么?继续分配?它必须停止一切,直到它可以释放内存。有一个开关可以显式关闭 System.gc() 提示,但我没有看到 CMS 或 G1 默认忽略它。
  • 我想这取决于您如何定义“完整集合” - 我不认为它是 JLS 或 VM 规范上下文中的一流术语。含义会根据您正在运行的特定 GC 算法而有所不同,甚至对于给定的 GC impl 可能没有意义。我想指出的是,唯一可能的一般性答案是“它取决于”,所有其他细节都推迟到特定垃圾收集器的内部。
  • 我认为完整的收藏有一个共同点。完全收集被定义为在线程停止的整个持续时间内的收集。即使 CMS 有一个短暂的暂停,当一个完整的收集发生时,整个 JVM 会在整个收集期间暂停。使用 CMS 的完整收集实际上是两次 CMS 运行 - 一次用于旧代,一次用于烫发。我想这和 G1 完全一样。
  • 本文给出了G1中Full collection的例子(增量收集失败时):blog.ragozin.info/2011/12/…。如果 Hotspot GC 日志识别出 Full GC 这个词,我认为它是相当官方的。

标签: java garbage-collection performance


【解决方案1】:

我观察到了另一种情况,它在 Ubuntu 上的 Java Hotspot VM 1.6 64 位中使用并发标记扫描触发完整 GC:

如果 -XX:PermSize 值不等于 -XX:MaxPermSize(例如更小),当 java 需要扩展 PermGen(即使它不需要分配比 MaxPermSize 更多的内存)时,偶尔会发生 Full GC。 因此,将 -XX:PermSize 和 -XX:MaxPermSize 设置为相同似乎是个好主意。

【讨论】:

  • 这是一个公认的答案吗? PermGenSpace 对 full gc 没有任何影响。你的意思是 xmx 和 xms 参数吗?
  • @Amareswar Oracle 说:“永久代包含在完整的垃圾收集中”
【解决方案2】:

这很大程度上取决于您的 jvm 选项和您使用的 jvm。

因此,我建议您阅读 John 和 Hunt 所著的《Java 性能》一书。

【讨论】:

  • 至少每个 JVM 实现和垃圾收集器都必须有一些通用规则。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 2014-03-09
  • 1970-01-01
相关资源
最近更新 更多