Java垃圾收集:次要,主要,完整

fgy*_*ica 5 java garbage-collection

我试图在大型企业Java应用程序中挂起垃圾收集.我有GC日志并开始使用各种工具查看它们 - 这里的截图是使用GCViewer完成的.(遗憾的是,没有更详细的GC信息的日志...)

我还在阅读我们正在使用的Java Hotspot VM垃圾收集.

但我仍然有些困惑:下面是GC图表放大部分的屏幕截图.

放大垃圾收集图

这里有三件事:

  1. 蓝线的"小曲折"(你几乎看不到):据我所知,这些是年轻空间中的 gc周期.
  2. 有一个黑色条,这是一个阻塞的10s全GC,可以在日志中看到:

    1751585.394: [Full GC 1433326K->660045K(1552832K), 10.1157600 secs]
    
    Run Code Online (Sandbox Code Playgroud)
  3. 然后是蓝线的"大曲折"(在左边的水滴中显示).这让我很困惑.

模式#3的日志不会将其标记为完整GC,但看起来与其他类似...

    1749795.648: [GC 1299871K(1552832K), 0.0402933 secs]
Run Code Online (Sandbox Code Playgroud)
  • 这也是一个次要GC吗?
  • 如果是,为什么同时发生两种不同的小型垃圾收集模式(#1和#3)?
  • 或者Young空间中的小GC和Tenured中的完整GC之间还有其他什么?

编辑.其他一些信息:
GC使用:并发Mark-Sweep GC
吞吐量为93.8%
最长暂停:10.116秒
暂停时间:6.21%

Jon*_*han 3

Java 的分代垃圾收集器有几种不同“种类”的垃圾收集。正如您所提到的,“小锯齿形”是年轻空间中的次要收集,而黑条将是完整的垃圾收集。为了简单起见,我将只描述正在发生的事情的最重要部分。

年轻代被划分为一个“伊甸园”空间和一个或多个“幸存者”空间。在这些小曲折之一期间,伊甸园空间中的死亡对象被移除,而存活对象被移动到幸存者空间之一。这是一个非常快的操作,因为代假设指出大多数对象都是短暂的。随后对幸存者空间的扫描可以将仍然存活的对象从幸存者空间移动到终身代中。这仍然被认为是一个小收藏。

我怀疑你在第一次大幅下降中看到的实际上是从幸存者一代到终身一代的“晋升”。

终身是年轻代中所有不够年轻的东西(这意味着,像许多其他 GC 选项一样,是可以调整的)。终身代比年轻代大得多,因此需要花费大量时间进行清理。当您谈论“完整”垃圾收集时,这是指对终身代(除了年轻代)的清理。

CMS 垃圾收集器会同时执行其执行的大部分操作,但仍需要停止对年轻代和终身代的标记操作。CMS 收集器在这方面应该非常快,即使对于大堆也是如此。然而,还有另一种情况会导致 CMS 停止运行:并发模式故障

暂停后的第二次大幅下降可能是由于这种情况造成的,当终身一代太满时就会发生这种情况。您可以调整终身代的大小和其他参数来避免这些问题。