【问题标题】:Garbage collection: how is Eden space (and the other generation sizes) calculated?垃圾收集:伊甸园空间(和其他代大小)是如何计算的?
【发布时间】:2012-08-03 13:06:12
【问题描述】:

我需要帮助来了解我从 jmapjstat 获得的与 GC 相关的数字与我传递给 java 的设置之间的关系。我在具有 16GB 内存的服务器上使用以下设置启动应用程序 (solr):

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-Xms12144m -Xmx12144m
-XX:NewRatio=4 -XX:SurvivorRatio=8 -XX:+UseCompressedOops

jmap 的输出开始于:

并发 Mark-Sweep GC 堆配置: MinHeapFreeRatio = 40 MaxHeapFreeRatio = 70 MaxHeapSize = 12733906944 (12144.0MB) 新大小 = 2686976 (2.5625MB) MaxNewSize = 130809856 (124.75MB) OldSize = 5439488 (5.1875MB) 新比率 = 4 幸存者比率 = 8 PermSize = 21757952 (20.75MB) MaxPermSize = 176160768 (168.0MB)

MaxHeapSize 很大时,为什么NewSizeMaxNewSizeOldSizePermSize 都那么小?不应该NewSize + OldSize = heap size吗?总堆大小不应该接近MaxHeapSize吗?当 NewRatio 设置为 4 时,为什么 NewSize 正好是 OldSize 的一半?

jmap 输出的其余部分如下。它与上述内容相匹配,并包含一个我也不知道如何解释的部分concurrent mark-sweep generation

此外,GC 日志表明“期望的幸存者大小”为 6.2MB,这也很奇怪,因为我知道 -XX:SurvivorRatio=8 应该使幸存者空间成为 NewSize 的 1/8。

最后,我只在我的 GC 日志中看到 ParNew 消息,我知道这是 Eden 的 GC。

堆使用: 新一代(伊甸园 + 1 个幸存者空间): 容量 = 117768192 (112.3125MB) 使用 = 20402232 (19.45708465576172MB) 免费 = 97365960 (92.85541534423828MB) 17.324059793666528% 已使用 伊甸空间: 容量 = 104726528 (99.875MB) 使用 = 16408336 (15.648208618164062MB) 免费 = 88318192 (84.22679138183594MB) 15.667793359863893% 已使用 从太空: 容量 = 13041664 (12.4375MB) 使用 = 3993896 (3.8088760375976562MB) 免费 = 9047768 (8.628623962402344MB) 30.624128945508794% 已使用 到太空: 容量 = 13041664 (12.4375MB) 使用 = 0 (0.0MB) 免费 = 13041664 (12.4375MB) 0.0% 已使用 并发标记扫描生成: 容量 = 12603097088 (12019.25MB) 使用 = 7903352408 (7537.22420501709MB) 免费 = 4699744680 (4482.02579498291MB) 62.70960505037411% 已使用 烫发一代: 容量 = 45903872 (43.77734375MB) 使用 = 27759192 (26.473228454589844MB) 免费 = 18144680 (17.304115295410156MB) 60.472441191889% 已使用

【问题讨论】:

    标签: java solr garbage-collection


    【解决方案1】:

    当 MaxHeapSize 很大时,为什么 NewSize、MaxNewSize、OldSize 和 PermSize 都那么小?

    尺寸只是它们需要的大小。如果你产生更多的短期垃圾,NewSize 会更大(我不知道 MaxNewSize 是如何设置的,但它通常比我设置的要小)

    并发标记扫描生成

    这有 capacity = 最大大小,used = 已使用,free = 容量 - 已使用。

    我的 GC 日志中的 ParNew 消息,据我所知是 Eden 的 GC。

    正如您所说,新空间很小,因此经常清理,而旧空间很大,因此很少清理。

    【讨论】:

    • 谢谢。关于设置:如果我在没有NewRatioSurvivorRatio 设置的情况下启动应用程序,NewSize 等实际上会增加 的大小。所以NewSize 的上限显然是由这个变量设置的。我认为它不是动态分配大小(您是在说什么?),因为NewSize 不会随着时间而改变。而关于concurrent mark-sweep generation——used 的大小显示为 7537MB,大概应该等于新旧加旧。但上面的输出显示OldSize 是 5.2MB。这些数字似乎都没有加起来,我仍然很困惑!
    • CMS 只清理旧的一代,因此不包括新的一代,4699744680 + 7903352408 = 12603097088 加起来很好。 ;) 您似乎在比较不同时间(第一次和第二次)取得的数字。它们会随着时间而变化。
    • 不,这些数字都来自同一个jmap 输出。第一组是输出的堆配置部分,第二组是Heap Usage 部分。我对(a)后半部分的数字和前半部分的数字之间的关系,以及(b)比例数字和前半部分的实际数字之间的关系感到困惑。我没有意识到但现在更清楚的是,标记为concurrent mark-sweep generation 的部分在其他地方称为tenured - 对吧?
    • tenured 空间是收集器的通用术语。我希望 concurrent mark-sweep generation 仅在您使用 CMS 时适用。我怀疑您需要再次运行指标收集,以确保同时收集数据。例如 jmap 在进行转储之前执行完整收集,因此只存储活动对象。数字可以显着减少是几分之一秒。我建议您在执行此操作时使用 visualvm 来监控堆空间,以确保您不会干扰我对它的监控。顺便说一句,使用 visualvm 也会干扰堆。
    • 太好了,谢谢,会的。然而,我还发现NewRatio 在使用 CMS 时的行为方式很奇怪,而且可能有问题。当使用-XX:NewSize=2g 设置显式NewSize 时,Heap ConfigurationHeap Usage 之间的关系更容易理解。
    猜你喜欢
    • 1970-01-01
    • 2012-03-06
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-10
    • 1970-01-01
    相关资源
    最近更新 更多