JVM 运行 旧代为 'empty' 时的旧代垃圾回收

JVM running old-gen garbage collection when old gen is 'empty'

我有一个 Clojure 应用程序 运行,它对大型堆分配有很多内存流失,因此它适当地设置了 JVM 选项:

-Xmx13g -XX:+UseConcMarkSweepGC -XX:NewSize=10G -server -XX:+UseParNewGC

这在大多数情况下都有效,并且避免了新生成溢出到旧生成中的问题(有时仍然会进入幸存者生成,但并非总是如此),但有时我们会看到 JVM 运行时如图所示的情况 CMS/old 当新一代已满时,gen 垃圾回收真的很难。不过,据我了解,这应该由新一代垃圾收集器处理。

两个问题。为什么老一代垃圾收集器 运行 老一代几乎是空的,而新一代有东西?我可以做任何进一步的调整来减少 GC pauses/slowdowns 这不可避免地导致的吗?

预计到达时间:运行 在 OpenJDK 8 上。

预计到达时间 2:GC 日志:https://gist.github.com/gworley3/6abb9ab52320c6cbd508

简答:

CMS 花费太多时间扫描将近 10GB 的 Young Gen,但它没有。您可以通过添加以下选项来防止 CMS 收集器不必要地 运行:

‑XX:+UseCMSInitiatingOccupancyOnly ‑XX:CMSInitiatingOccupancyFraction=<K>

其中 K 是被占领老一代 space 的任意分数。

长答案:

参考Oracle CMS Documentation

The CMS collector pauses an application twice during a concurrent collection cycle. The first pause is to mark as live the objects directly reachable from the roots (for example, object references from application thread stacks and registers, static objects and so on) and from elsewhere in the heap (for example, the young generation). This first pause is referred to as the initial mark pause. The second pause comes at the end of the concurrent tracing phase and finds objects that were missed by the concurrent tracing due to updates by the application threads of references in an object after the CMS collector had finished tracing that object. This second pause is referred to as the remark pause.

CMS 进行两次 stop-the-world 暂停,每次扫描 Young Gen 进行标记。查看日志的前三行,您可以看到初始标记在 ParNew 之前用了 5 秒,在 ParNew 之后用了 0.25 秒。这句话在时间上看到了类似的减少。

<190>1 2015-12-18T08:44:54.194216+00:00 host app web.1 - [GC[YG occupancy: 489826 K (9437184 K)][Rescan (parallel) , 0.2520950 secs][weak refs processing, 0.0000180 secs][scrub string table, 0.0008190 secs] [1 CMS-remark: 64504K(107240K)] 554330K(9544424K), 0.2530410 secs] [Times: user=1.95 sys=0.02, real=0.25 secs]

<190>1 2015-12-18T08:44:49.937257+00:00 host app web.1 - [GC[ParNew:   8418004K->93508K(9437184K), 0.0488580 secs] 8482343K->158013K(9544424K), 0.0489980 secs] [Times: user=0.33 sys=0.00, real=0.05 secs]

<190>1 2015-12-18T08:44:48.651086+00:00 host app web.1 - [GC [1 CMS-initial-mark: 64339K(107240K)] 7800216K(9544424K), 5.0756660 secs] [Times: user=5.08 sys=0.00, real=5.08 secs]

你的老一代 space 在每个 CMS 周期后几乎没有减少,所以开销当然不值得。减少 CMS 循环的频率将是一种可能的解决方案。