JVM ClassUnloadingWithConcurrentMark 标志

JVM ClassUnloadingWithConcurrentMark flag

我对 ClassUnloadingWithConcurrentMark 标志有疑问,因为我没有在任何地方找到任何有用的帮助。如果我们使用 G1GC,则默认设置为 true (-XX:+ClassUnloadingWithConcurrentMark)。如果我在 G1 并发标记后使用 -XX:-ClassUnloadingWithConcurrentMark 标志关闭 class 卸载,那么 class 卸载在哪里执行(哪个阶段)?我在某处读到,当完全 GC 被激活时会发生这种情况,如果从未触发完全 GC 怎么办?我在长评论阶段遇到问题 - 在下面的示例中卸载花费了超过 3 秒:

2015-06-08T08:09:16.318+0200: 572818.729: [GC remark 572818.729: [Finalize Marking, 0.0002590 secs] 572818.729: [GC ref-proc, 0.4479462 secs] 572819.177: [Unloading, 3.2004912 secs], 3.6499382 secs]
 [Times: user=0.20 sys=0.08, real=3.64 secs] 

使用 -XX:-ClassUnloadingWithConcurrentMark 对我减少 class 卸载时间有用吗?我担心如果我使用这个选项我会遇到更多的问题(例如内存不足异常,...)如果 class 卸载永远不会发生。

编辑:如果我们使用 -XX:+ClassUnloadingWithConcurrentMark(默认选项)是 class 每次 GC 注释阶段发生时都会触发卸载?在日志中我有一些 GC 与 GC 原因:元数据 GC 阈值,但其他人没有这个原因但卸载仍然发生在评论阶段。为什么会这样?

I'm afraid that If I'll use this option I'll have even more problems

你为什么不为这些东西搭建一个测试环境然后自己测试呢?

无论如何,正如已经回答的over here,VM 将执行一些最后的英雄行为(1-2 次完整的 GC,完全软引用清除)以确保在抛出 OOM 之前情况不可恢复。

Would using -XX:-ClassUnloadingWithConcurrentMark be useful to me to reduce class unloading times?

会不会减少,我不知道,可能不会。这就是你必须自己尝试的。但它可能会延迟很长一段时间。

if we are using -XX:+ClassUnloadingWithConcurrentMark (default option) is class unloading triggered every time GC remark phase occurs?

是的,这是用 JDK-8049421 and the flag to turn it off again with JDK-8051607 添加的。

您所要做的就是在 openjdk bugtracker and/or hotspot-gc-dev 邮件列表中搜索 "class unloading"。这是所有 public 信息。


您可以尝试的另一件事是设置 -XX:MinMetaspaceFreeRatio=20 -XX:MaxMetaspaceFreeRatio=30。这将触发 class 卸载 更快 并希望导致更短的周期。

G1 在 STW Remark 阶段执行 class 卸载,这是默认行为。 您无法阻止 class 卸载,因为这样做最终会导致 "Out of Memory" 错误。

缓解此问题的唯一方法是修改您的代码以停止使用动态 classes 生成。