【问题标题】: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?

为此,您应该拥有CMSClassUnloadingEnabledUseConcMarkSweepGC。当永久区域达到其阈值时,将触发 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
    相关资源
    最近更新 更多