JVM在RHEL 5.2的压力下崩溃

che*_*vim 10 java crash jvm rhel segmentation-fault

4到24小时 4小时到8天的压力测试(30个线程点击应用程序)后,我在(当前最新的)tomcat 6.0.24上运行了一个Web应用程序(当前最新的)jdk 1.6.0.18崩溃了6 mil.综合浏览量/天).这是RHEL 5.2(Tikanga).

崩溃报告位于http://pastebin.com/f639a6cf1,崩溃的一致部分是:

  • 正在抛出一个SIGSEGV
  • 在libjvm.so上
  • 伊甸园空间永远满(100%)

JVM使用以下选项运行:

CATALINA_OPTS="-server -Xms512m -Xmx1024m -Djava.awt.headless=true"
Run Code Online (Sandbox Code Playgroud)

我还使用http://memtest.org/测试了内存中的硬件问题48小时(整个内存14次通过)没有任何错误.

我已经能够-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps检查任何GC趋势或空间耗尽,但那里没有任何可疑之处.GC和完整GC以可预测的间隔发生,几乎总是释放相同数量的内存容量.

我的应用程序不直接使用任何本机代码.

关于我接下来要去哪看的任何想法?

编辑 - 更多信息:

1)这个JDK中没有客户端vm:

[foo@localhost ~]$ java -version -server
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)

[foo@localhost ~]$ java -version -client
java version "1.6.0_18"
Java(TM) SE Runtime Environment (build 1.6.0_18-b07)
Java HotSpot(TM) 64-Bit Server VM (build 16.0-b13, mixed mode)
Run Code Online (Sandbox Code Playgroud)

2)无法更改操作系统.

3)我不想更改JMeter压力测试变量,因为这可以隐藏问题.因为我有一个崩溃JVM的用例(当前的压力测试场景),我想修复崩溃而不是改变测试.

4)我对我的应用程序进行了静态分析,但没有出现任何严重问题.

5)记忆力不会随着时间的推移而增长.内存使用率非常快(在启动后)以非常稳定的趋势平衡,这似乎并不可疑.

6)/ var/log/messages在崩溃之前或期间不包含任何有用的信息

更多信息:忘了提到有一个使用mod_jk 1.2.28的apache(2.2.14)前面的tomcat.现在我正在运行没有apache的测试,以防万一JVM崩溃与连接到JVM(tomcat连接器)的mod_jk本机代码有关.

之后(如果JVM再次崩溃)我将尝试从我的应用程序中删除一些组件(缓存,lucene,石英),稍后将尝试使用jetty.由于崩溃目前发生在4小时到8天之间的任何时间,因此可能需要花费大量时间才能找出正在发生的事情.

Mat*_*att 4

你有编译器输出吗?即PrintCompilation(如果你感觉特别勇敢,LogCompilation)。

我通过观察编译器正在做什么来调试这样的情况,最终(这花了很长时间直到灯泡时刻),意识到我的崩溃是由 oracle jdbc 驱动程序中的特定方法的编译引起的。

基本上我会做的是;

  • 打开 PrintCompilation
  • 因为它没有给出时间戳,所以编写一个脚本来监视该日志文件(例如每秒睡眠一次并打印新行)并报告方法何时被编译(或不编译)
  • 重复测试
  • 检查编译器输出以查看崩溃是否与某些方法的编译相对应
  • 多重复几次,看看是否有规律

如果存在可辨别的模式,则使用 .hotspot_compiler (或 .hotspotrc)使其停止编译有问题的方法,重复测试并查看它是否不会崩溃。显然,在你的情况下,这个过程理论上可能需要几个月的时间。

一些参考资料

我要做的另一件事是系统地更改您正在使用的 gc 算法,并根据 gc 活动检查崩溃时间(例如,它与新的还是旧的 gc 相关,TLAB 又如何?)。您的转储表明您正在使用并行清除,因此请尝试

  • 串行(年轻)收集器(IIRC 它可以与并行旧收集器结合使用)
  • 帕新+CMS
  • G1

如果它在不同的 GC 算法中没有重复出现,那么你就知道是这个原因(并且你没有解决办法,只能更改 GC 算法和/或返回旧的 JVM,直到找到不会崩溃的该算法的版本) )。