我的JBoss服务器在Linux上遇到100%的SYS CPU; 什么可以导致这个?
我们一直在调试这个JBoss服务器问题。 经过大约10个小时的工作,服务器进入100%CPU恐慌攻击并停止。 在此期间,您无法运行任何新程序,因此您甚至无法使用kill -quit
来获取堆栈跟踪。 这些高100%SYS CPU负载持续10-20秒,每隔几分钟重复一次。
我们已经工作了很长一段时间。 我们怀疑它与GC有关,但无法通过较小的程序确认。 我们使用-client
和ParNew GC
在i386 32位,RHEL5和Java 1.5.0_10上运行。
以下是我们迄今为止所尝试的内容:
-
我们限制了CPU亲和力,因此我们可以在高负载点击时实际使用服务器。 随着
strace
我们看到一个无限循环的SIGSEGV
然后sig返回。 -
我们尝试使用Java程序重现这一点。 确实,SYS CPU%使用
WeakHashMap
或访问空指针时爬升得很高。 问题是fillStackTrace
占用了大量用户CPU%,这就是我们从未达到过100%SYS CPU的原因。 -
我们知道,经过10个小时的压力,GC会变得疯狂,完整的GC有时需要5秒钟。 所以我们假设它与记忆有关。
-
在此期间的
jstack
显示所有线程都被阻止。pstack
在那段时间里偶尔出现MarkSweep堆栈跟踪,所以我们也不能确定这一点。 发送SIGQUIT
没有任何结果:Java在SYS%加载周期结束后转储了堆栈跟踪。
我们现在尝试用一小段代码重现这个问题,这样我们就可以问Sun.
如果您知道是什么原因造成的,请告诉我们。 我们对想法持开放态度,我们无能为力,欢迎任何想法:)
谢谢你的时间。
感谢大家帮忙。
最终我们升级了(只有一半的java服务器)到JDK 1.6,问题就消失了。 只是不要使用1.5.0.10 🙂
我们设法通过访问空指针来重现这些问题(提升SYS而不是US,并杀死整个linux。)
再次感谢大家。
如果您确定GC是问题(并且它听起来像是基于您的描述),那么将-XX:+ HeapDumpOnOutOfMemoryError标志添加到您的JBoss设置可能会有所帮助(在JBOSS_HOME / bin / run.conf中)。
您可以在此处阅读有关此标志的更多信息 它最初是在Java 6中添加的,但后来被后端移植到Java 1.5.0_07。
基本上,如果发生OutOfMemoryError,您将获得“转储文件”,然后可以在各种分析工具中打开它。 我们在Eclipse Memory Analyzer上运气不错。
这不会给你任何“免费”答案,但如果你确实有内存泄漏,那么这将帮助你找到它。
您是否尝试过分析应用程序。 有一些很好的性能分析应用程序可以在生产服务器上运行。 如果GC遇到麻烦以及哪些对象,那些应该给你
我去年遇到了与JBoss(JBoss 4,Linux 2.6)类似的问题。 我认为最终它确实与应用程序错误有关,但它绝对很难弄明白。 我会继续尝试向进程发送’kill -3’,以获得某种堆栈跟踪并找出阻塞的内容。 也许添加日志记录语句,看看你是否可以弄清楚是什么设置它。 您可以使用’lsof’来确定它打开的文件; 这将告诉您是否存在除内存之外的某些资源的泄漏。
另外,为什么用-client而不是-server运行JBoss? (不是我认为在这种情况下它会有所帮助,只是一个普遍的问题)。
您可以尝试添加命令行选项-verbose:gc,它应该将GC和堆大小输出到stdout。 将stdout传递给文件,看看高cpu时间是否与主要gc对齐。
我记得在Windows上遇到与JBoss类似的问题。 cpu会定期100%,并且Windows报告的内存使用量会突然下降到2.5 MB,比运行JBoss要小得多,并在几秒钟后自行备份。 好像整个服务器都关闭并重新启动。 我最终将我的问题跟踪到Apache Commons中一个永不过期的预准备语句缓存。
如果它确实是一个内存问题,那么你可以开始定期堆转储并比较两者,或使用类似JProbe Memory profiler的东西来跟踪所有内容。