1 现象
场景:LoadRunner 10用户并发,无思考时间,每个用户顺序执行59个交易。
现象:压测10-15分钟之后,LoadRunner客户端发现大量失败交易,查看错误信息“无法连接应用服务器”。应用服务器发现产生大量heapdump.***.phd和javacore.***.txt文件。
2 初步定位
分析应用日志ltts-app1.out,发现存在如下错误信息:
Throwable occurred: java.lang.OutOfMemoryError: Java heap space at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:480) at java.net.ServerSocket.implAccept(ServerSocket.java:479) at java.net.ServerSocket.accept(ServerSocket.java:447) at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:381) at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:353) at java.lang.Thread.run(Thread.java:738) |
同时,在应用程序启动目录下发现存在多个javacore*.txt、heapdump*.phd文件,初步定为为堆内存泄露问题。
3 问题还原
增加应用JVM启动选项,降低堆最大内存大小至1024m来减少问题暴露的时间。
--堆内存大小 -Xms768m -Xmx2048m
--开启jconsole监控端口 -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxr emote.authenticate=false
--开启verbosegc -verbose:gc -Xverbosegclog:gc.log
--自定义heapdump事件和格式 -Xdump:heap:events=user |
应用启动成功后,通过jconsole连接上去查看初始堆内存大小。
此时,通过“kill -3 pid”主动产生javacore和heapdump转储文件,作为基线参考。
接着,开始通过Load Runner压测,过了3分钟、5分钟左右,通过“kill -3 pid”主动产生javacore和heapdump转储文件,作为时点数据可以与基线数据进行比较。
Load Runner压测10-15分钟左右,通过jconsole跟踪发现堆内存持续增长,垃圾回收也无法释放内存。
另外,通过AIX命令tprof命令“tprof -s -k -x sleep 60”跟踪java进程cpu使用情况。
Process Freq Total Kernel UserShared Other ======= ==== ===== ====== ==== ====== ===== wait 16 53.07 53.07 0.00 0.00 0.00 /usr/java5/jre/bin/java 38 45.66 1.06 0.00 42.00 2.60
可以看出Shared(即动态库cpu占比很高),接下来查看哪些动态库占用cpu较多呢? Total % For All Processes (SH-LIBs) = 42.06
Shared Object % ============= &n |