我的JBoss服务器在Linux上遇到100%的SYS CPU; 什么可以导致这个?

我们一直在调试这个JBoss服务器问题。 经过大约10个小时的工作,服务器进入100%CPU恐慌攻击并停止。 在此期间,您无法运行任何新程序,因此您甚至无法使用kill -quit来获取堆栈跟踪。 这些高100%SYS CPU负载持续10-20秒,每隔几分钟重复一次。

我们已经工作了很长一段时间。 我们怀疑它与GC有关,但无法通过较小的程序确认。 我们使用-clientParNew GC在i386 32位,RHEL5和Java 1.5.0_10上运行。

以下是我们迄今为止所尝试的内容:

  1. 我们限制了CPU亲和力,因此我们可以在高负载点击时实际使用服务器。 随着strace我们看到一个无限循环的SIGSEGV然后sig返回。

  2. 我们尝试使用Java程序重现这一点。 确实,SYS CPU%使用WeakHashMap或访问空指针时爬升得很高。 问题是fillStackTrace占用了大量用户CPU%,这就是我们从未达到过100%SYS CPU的原因。

  3. 我们知道,经过10个小时的压力,GC会变得疯狂,完整的GC有时需要5秒钟。 所以我们假设它与记忆有关。

  4. 在此期间的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的东西来跟踪所有内容。