【问题标题】:Is Concurrent Mark Sweep (CMS) a stop the world event?Concurrent Mark Sweep (CMS) 是一项停止世界活动吗?
【发布时间】:2014-01-20 09:20:22
【问题描述】:

我看到很多类卸载,我的整个系统在这段时间内都会挂起..

[Unloading class sun.reflect.GeneratedMethodAccessor117]
[Unloading class sun.reflect.GeneratedConstructorAccessor1896]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor485]
[Unloading class sun.reflect.GeneratedSerializationConstructorAccessor579]
.... // about 1700 of them

同时我没有看到烫发空间出现峰值,所以这似乎不是 GC 事件。

我想知道以下内容

Concurrent Mark Sweep 收集是停止世界事件吗?

烫发空间未满时也会出现这种情况吗?

【问题讨论】:

  • 见this JDK bug report,它可能是相关的。这些消息的打印可能是您挂起的原因(即使没有提到关闭stdout)。您使用的是旧版本的 Java 运行时吗?

标签: java garbage-collection jvm concurrent-mark-sweep


【解决方案1】:

CMS是GC的一种,分为阶段

你可以看到两个阶段 - 初始标记和备注是停止世界事件。

Source :在Reviewing Generational GC and CMS 部分下。

Does it happen even when the perm space is not full?

为此,您应该拥有CMSClassUnloadingEnabled 和UseConcMarkSweepGC。当永久区域达到其阈值时,将触发 FGC。

虽然并发扫描(短语 (4))不是 STW 事件,但如果 permgen 区域被填满(并且 GC 仍在处理 permgen 区域),它可能会导致停止所有进程线程并且只有 GC 线程运行直到所有需要的内存被回收。

【讨论】:

  • 我可以假设卸载类 sun.reflect -> 在短语 (4) 中吗?
  • 这个字面的copypasta无助于回答OP的具体问题。
【解决方案2】:

CMS 不是“事件”。它是一个垃圾收集器。 CMS 确实有几个阶段会停止一切,但在正常情况下,这些阶段非常短(几毫秒)。一般来说,如果你得到一个长时间的停顿,这意味着 CMS 无法跟上垃圾生成的速度(在已设置的约束范围内),并且 JVM 必须使用“ mark-sweep" 收集器 ... 是 停止世界。

根据您的 JVM,可能仅在发生完整 GC 时才收集 permgen,并且仅在 permgen 被 GC 时收集/卸载类。

但是你不能推断类卸载导致长时间的停顿。事实上,如果您的 GC 统计数据显示 permgen 没有填满,则更有可能是相反的情况。

您的日志记录类卸载也有可能导致“停止世界”问题:请参阅http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6637203


观察:

  • 如果您有成千上万条关于卸载动态创建的类的消息,那么我会看看您的系统架构。您是否过度使用代理类?

  • 在 Java 8 中,permgen 消失并被元空间取代。升级可能会缓解您的问题。

【讨论】:

    【解决方案3】:

    通常 perm gc 不会造成挂断问题。

    原因是,Perm 通常在应用程序中的所有类都已加载后稳定下来。 这可能是挂断的结果。 这意味着,如果 JVM 没有足够的内存。它尝试进行 Full-GC。作为完整 gc 的一部分,Perm 将被 GC。

    关于你问的问题 CMS 还提供 Full GC。它只是减少了 Full GC 的数量。在 Minor GC 期间,它还会收集 Old 内存区域。

    在我看来,您可能在堆内存中遇到问题,它会导致 # 次 Full GC 并导致挂起问题。所以你需要使用 Visual JVM 工具或一些 GC 日志分析来检查内存使用情况。您可能会发现 Old 内存区域已满,JVM 尝试对它进行 GC。但是没有释放足够的内存,它会重试 gc 。并重试重试..等等。

    我认为您可能有内存泄漏。问题。所以最好是GC日志分析,如果是内存泄漏问题,你需要堆转储并分析它。

    【讨论】:

    • “Perm 通常在所有类被加载后稳定”对于某些应用程序可能是正确的,但显然不是 OP,它显示了在运行时通过优化生成的临时类的卸载在名为 inflation 的反射 API 中。这一点也不稀奇,大多数应用程序出于某种目的而动态生成字节码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2013-02-18
    • 2019-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多