我看到许多类的卸载,我的整个系统将在这段时间内挂起..
[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收集世界事件的停止?
即使烫发空间不满也会发生吗?
答案 0 :(得分:19)
CMS是一种GC,分为几个阶段
您可以看到两个阶段 - 初始标记和备注将停止世界事件。
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日志分析更好,如果是内存泄漏问题,你需要进行堆转储并对其进行分析。