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

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

[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收集了一个停止世界事件?

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

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

在此处输入图像描述

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

资料来源 :在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线程运行直到回收所有所需的内存。

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

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

但是你无法推断出类卸载会导致长时间停顿。 事实上,如果您的GC统计数据表明permgen没有填满,那么更有可能反过来。

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


观察:

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

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

通常perm gc不会挂起问题。

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

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

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

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