案例背景
环境:现场生产环境,SunOS 5.10 + WAS 8.5 + oracle
问题描述:现场人员反馈PM服务所在的SERVER频繁自动重启,导致系统无法使用,业务无法开展。

分析过程
因为SERVER会自动重启,所以首先想到的是内存溢出,因为WAS的SERVER,默认情况下在内存溢出后会自动重启。

现场的操作系统是SunOS 5.10,这个操作系统上面的WAS,用的是Sun JDK,而非WAS 自带的IBM JDK,记住这一点。

查看WAS日志目录下的native_stdout文件,发现在重启的时间点,WAS自动生成了一次Full thread dump Java。
 

性能测试性能瓶颈问题分析调优案例_性能测试

在thread dump的最后,可以看到Heap使用情况,PSPermGen使用了99%,已经满了,大小约为256M,其他分区的使用量还比较低。

性能测试性能瓶颈问题分析调优案例_软件测试_02

检查内存溢出时的线程堆栈信息,主要查看webcontainer的线程和dubbo线程的信息,看是否存在可疑的会一次性查询或者加载大量数据的操作,并未发现这类问题。

网上搜索PSPermGen溢出的相关资料,发现这块区域存储的并非数据,而是一些类型之类的,建议的解决方式都是通过增大这块内存大小。

对这个SERVER开启JMX监控,发现SERVER带着包启动之后,PSPermGen区就已经几乎是满的了。

监控方式:
-Djavax.management.builder.initial= -Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.port=3090

监控结果:
 

性能测试性能瓶颈问题分析调优案例_性能测试_03

 这与IBM JDK JVM的结构有很大不同。

性能测试性能瓶颈问题分析调优案例_性能测试_04

jmap -dump:format=b,file=/opt/HeapDump.bin 5010获取HeapDump,看不出明显的问题,交由开发进一步查看定位。

解决问题
公司的客户环境大多是WAS + IBM JDK ,在这种环境下没有这个问题。

于是只好先把这里的PSPermGen的大小调整到512M,暂时解决这个问题。

设置JVM参数:-XX:PermSize=256M -XX:MaxPermSize=512M

设置后的JVM图:
 

性能测试性能瓶颈问题分析调优案例_软件测试_05

总结
IBM JDK与Sun JDK 差别很大,JVM 内存区域的分区和实现方式都不一样,在这两种JDK上生成的线程快照形式也完全不一样。

介于当时的技术认知水平,没有继续对这个问题进行深入研究。