在对Tomcat的多次压力测试中,在配置-Xmx512m情况下,发送25万多条,就会导致内存耗尽,频繁Full GC(最后几乎不能再响应任何请求,一直在Full GC),说明内存没有释放。尝试了Tomat 6.0.20和7.0.5,行为一致。开始猜测如下两种可能
1. 内存泄漏
2. 每次请求都消耗了一定资源(约2.5k),需要等待session过期才能释放。
第一种可能性只是猜测,毕竟Tomcat已经久经考验。接下来,试图证实第二种可能性。
使用ApacheBench压测Tomcat 7.0.5。请求的是一个小JSP文件。
之前的多次测试,确认在AMD Tourion双核1.8G Hz CPU, 2G内存上,5个线程并发能达到最大的吞吐。
Tomcat的JVM启动参数:
-server -Xms1024m -Xmx1024m -Xloggc:../gc.log
在另一台Ubuntu(Intel T4400,4G)上使用如下命令执行压测:
ab -k -n 500000 -c 5
http://192.168.0.100/service/index.jsp
从gc日志上看,内存没有耗尽。除了启动后的几秒钟内,发生了一次Full GC,之后很长一段时间都没有发生Full GC(因为-Xms配置成了和-Xmx一样大的关系)
GC历史:
3.965: [GC 12278K->1528K(1034048K), 0.0431287 secs]
4.009: [Full GC 1528K->1491K(1034048K), 0.1296874 secs]
41.157: [GC 88915K->20402K(1034048K), 0.0913074 secs]
… 期间内存消耗持续增长,到此,50万请求发送完成
157.368: [GC 895732K->853672K(1021824K), 0.3552454 secs]
… 约半小时后(正好是默认的Session过期时间),开始回收内存
1899.550: [GC 915836K->863741K(998592K), 0.2737393 secs]
3604.205: [GC 912483K->864412K(1017152K), 1.1948597 secs]
请求发送完成1小时后,发生Full GC,回收了800M左右的内存
3605.400: [Full GC 864412K->53546K(1017152K), 1.5894679 secs]
… 在之后的7小时内,发生若干次Full GC,最终,内存消耗跌回8M以内。
25209.237: [Full GC 7627K->7627K(1017536K), 0.3135709 secs]
观察总结:
内存在半小时后,开始释放。一小时后,触发Full GC,回收800M,之后的几个小时内,几乎是每小时定时Full GC一次(估计是服务器版的JVM的某种GC算法).
推论:
每次对Tomcat请求,都会积累延时释放的内存资源。相信就是Session相关资源(尽管所有测试请求都只是简单地打印出请求响应头)。