一次压测中tomcat生成session释放不及时导致的频繁fullgc性能优化案例

性能问题:老年代一直处于占满状态,为什么没有发生内存溢出

以HotSpot VM的分代式GC为例,普通对象分配都是在young gen进行的,具体是从在位于young gen中的eden space中分配的TLAB里分配的。

就算old gen已经接近占满其最大capacity,由于新对象的分配都在young gen而如果young GC总是能回收足够空间来避免进一步有对象需要晋升到old gen的话,那就可以一直运行下去而不OOME。

另外一种情况就是其实程序已经进入了不断full GC来试图回收空间的状态,碰巧每次full GC都能回收刚好够用的空间,而GC占用的时间未超过98%的话,那程序也还会继续拖着拖着向前爬而不抛OOME。

还有其它各种情况,不看具体日志无从分析起。
 
压测接口如下:

其实就是app里面的一个图片轮播图

现象如下:

发现高并发下,配置的1g的jvm很快就会涨到600-900M,即使通过fullgc也无法回收到低位

通过手动触发fullgc也是无法回到低位

现象1:

现象2:

tps极其不稳定,波动范围较大

 根据自己性能测试经验判断,这里肯定存在对象释放缓慢,导致内存释放不彻底的性能问题

解决问题的思路:

既然内存释放不彻底,那就看内存中有啥呗

通过java命令jmap查看当前存活的对象

jmap -dump:live,format=b,file=/tmp/heap20434.hprof 20434

通过MAT分析工具查看内存热点

 分析2:

 由以上知道,org.apache.catalina.session.StandardManager类产生大量的对象

原来有那么session霸占这map对象,api根本就没有使用tomcat的session,这么单纯的网站和session有啥关系呢,我以前还一直以为只有动态存放session内容的时候,才会创建session对象

4.解决问题

1.既然是session的问题,首选更改tomcat项目的web.xml中的tomcat session的超时间

更改后,重新压测,还是没有回收正常

2.通过查看源码:

发现代码中在不断的创建session对象,这个是tomcat本身大量创建的

 

request.getSession().invalidate(); //通过这句,清空session对象

修改后,重新压测如下:

第一轮优化后

 

 

posted @ 2017-08-28 18:59  Agoly  阅读(1678)  评论(1编辑  收藏  举报