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

标签 java garbage-collection

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

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

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

Zoom on garbage collection graph

这里发生了三件事:

  1. 有蓝线的“小锯齿形”(您几乎看不到):据我了解,这些是在年轻空间中发生的次要 gc 周期。
  2. 有黑条,这是一个阻塞的 10s full GC,可以在日志中看到:

    1751585.394: [Full GC 1433326K->660045K(1552832K), 10.1157600 secs]
    
  3. 然后是蓝线的“大之字形”(体现在左边的水滴中)。 这就是让我感到困惑的地方。

模式 #3 的日志没有将其标记为完全 GC,但看起来与其余模式类似...

    1749795.648: [GC 1299871K(1552832K), 0.0402933 secs]
  • 那么这也是次要 GC 吗?
  • 如果是,为什么会同时发生两种不同的次要垃圾收集模式(#1 和#3)?
  • 或者在 Young 空间中的次要 GC 和 Tenured 空间中的完整 GC 之间是否存在其他问题?

编辑。一些附加信息:
使用的 GC:Concurrent Mark-Sweep GC
吞吐量为 93.8%
最长停顿:10.116 秒
暂停时间:6.21%

最佳答案

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

年轻代被划分为一个“伊甸园”空间和一个或多个“幸存者”空间。在其中一个小之字形中,伊甸园空间中的死对象被移除,活对象被移动到幸存者空间之一。这是一个非常快速的操作,因为 分代假设指出大多数对象都是短暂的。随后对幸存者空间的扫描可能会将仍然存在的对象从幸存者空间移动到终身代。这仍然被视为次要集合。

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

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

CMS 垃圾收集器并发操作它所做的大部分事情,但仍需要 stop the world用于对年轻一代和老一代进行标记操作。 CMS 收集器在这方面应该非常快,即使对于大堆也是如此。然而,还有一种情况是 CMS 停止了世界:concurrent mode failure .

暂停后的第二次大跌可能是这个原因造成的,发生在老一代太满的时候。您可以调整老年代的大小和其他参数来避免这些。

关于Java 垃圾收集 : minor, 主要,完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25724175/

相关文章:

java - 有界基元

java - 在android中实现滑动菜单的步骤是什么或者有任何代码

c# - 为什么 AppDomain.Unload() 在终结器中出错?

memory-management - 你什么时候不想使用垃圾收集?

garbage-collection - QML 内存管理

java - 如何在 println() 中自动调用 toString()

java - 测试 SQL Server 驱动程序是否存在

java - Selenium 2 : New Browser Has No Bookmarks

java - gc.logs 应该检查什么

c# - GC.Collect() 阻塞了吗?