Concurrent Mark Sweep(CMS)是否能阻止世界事件?

时间:2014-01-20 09:20:22

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

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

[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事件。

我想知道以下内容

IS Concurrent Mark Sweep收集世界事件的停止?

即使烫发空间不满也会发生吗?

3 个答案:

答案 0 :(得分:19)

CMS是一种GC,分为几个阶段

enter image description here

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

Source:在Reviewing Generational GC and CMS部分。

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

对于AFAIK,你应CMSClassUnloadingEnabled UseConcMarkSweepGC。当permgen面积达到阈值时,将触发FGC。

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

答案 1 :(得分:4)

CMS不是“事件”。这是一个垃圾收集器。 CMS确实有几个阶段,一切都停止了,但在正常情况下,这些阶段非常短(几毫秒)。通常,如果长时间停顿,则意味着CMS无法跟上垃圾生成速度(在已设置的约束内),并且JVM必须使用“执行完全GC”。标记扫描“收集器...... 阻止世界。

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

但你不能推断出卸载的类导致长暂停。事实上,如果您的GC统计数据表明permgen没有填满,则更有可能反过来。

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


观察:

  • 如果您有数千条关于卸载动态创建的类的消息,那么我将介绍一下系统的体系结构。您是否过度使用代理类?

  • 使用Java 8,permgen消失并被metaspace取代。升级可以缓解您的问题。

答案 2 :(得分:1)

通常perm gc不会挂起问题。

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

关于你问的问题 CMS也生产Full GC。它只是减少Full GC的#。在Minor GC期间,它还收集旧内存区域。

在我看来,你可能在堆内存中遇到问题而且它会产生一个完整的GC并且会出现挂起问题。因此,您需要使用Visual JVM工具或某些GC日志分析来检查内存使用情况。您可能会发现旧内存区域已满,JVM尝试将其GC格式化。但没有释放足够的内存,它重试gc。并重试重试..等等。

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