我们有一个基于Web的应用程序运行在JBoss上,允许的最大堆大小约为2.2GB(年轻一代为400 GB,机器物理内存总量为4GB)。在某个时候,应用程序停止响应(客户端)几分钟。经过分析,我们发现罪魁祸首是年轻一代的GC。下面是详细GC日志的摘录:
Heap before GC invocations=3844 (full 7):
par new generation total 614336K, used 614272K, eden space 614272K, 100% used, from space 64K, 0% used, to space 64K, 0% used , concurrent mark-sweep generation total 921600K, used 690936K, concurrent-mark-sweep perm gen total 262144K, used 65905K 2679114.965: [GC 2681684.725: [ParNew: 614272K->0K(614336K), 0.0132460 secs] 1305208K->692360K(1535936K), 0.0135020 secs] [Times: user=0.03 sys=0.03, real=2569.62 secs]
Heap after GC invocations=3845 (full 7):
par new generation total 614336K, used 0K, eden space 614272K, 0% used, from space 64K, to space 64K, 0% used, concurrent mark-sweep generation total 921600K, used 692360K, concurrent-mark-sweep perm gen total 262144K, used 65905K
Total time for which application threads were stopped: 2569.7748610 seconds我不明白的是,为什么ParNew GC上的实时时间大约为42分钟(2569秒),而user+sys时间仅为0.06秒,次要集合的暂停时间仅为0.0132460秒。
我们猜测“虚拟内存破坏”或“高cpu负载”可能会导致这个问题,我们测试了两种情况:
。
这两种情况中的任何一种,年轻一代GC的时间都会变长,但次要集合的暂停时间大约等于实时,似乎没有任何一种会导致以上的长时间暂停。
但其他时间都去哪儿了?
发布于 2011-12-03 07:30:57
在停止之前,可以执行世界GC,所有线程都必须到达安全点。通常情况下,这种情况会很快发生,但是一些JNI方法可能在没有safepoint的情况下运行很长时间。这是一个原因之一,你可以得到一个很长的延迟,才能真正开始一个GC。
如果您再次看到这一点,则值得获得C级堆栈跟踪(在执行GC之前,j堆栈很可能不会响应)。
https://stackoverflow.com/questions/8366274
复制相似问题