【发布时间】: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