7.3.5 Tomcat堆溢出分析(1)

实战Java虚拟机:JVM故障诊断与性能优化》第7章分析Java堆,本章主要介绍了Java堆的分析方法。首先,介绍了几种常见的Java内存溢出现象及解决思路。其次,探讨了java.lang.String类的特色,以及在JDK 1.6和JDK 1.7中的改进与区别。本节为你们介绍Tomcat堆溢出分析。java

做者:葛一鸣来源:电子工业出版社|2015-04-14 17:20

开发者大赛路演 | 12月16日,技术创新,北京不见不散


7.3.5  Tomcat堆溢出分析(1)性能优化

Tomcat是最经常使用的Java Servlet容器之一,同时也能够当作单独的Web服务器使用。Tomcat自己使用Java实现,并运行于Java虚拟机之上。在大规模请求时,Tomcat有可能会由于没法承受压力而发生内存溢出错误。本节根据一个被压垮的Tomcat的堆快照文件,来分析Tomcat在崩溃时的内部状况。服务器

图7.22显示了Tomcat溢出时的整体信息,能够看到堆的大小为29.7MB。从统计饼图中得知,当前深堆最大的对象为StandardManager,它持有大约16.4MB的对象。session

通常来讲,咱们老是会对占用空间最大的对象特别感兴趣,若是能够查看StandardManager内部究竟引用了哪些对象,对于分析问题可能会起到很大的帮助。所以,在饼图中单击StandardManager所在区域,在弹出菜单中选择“with outgoing references”命令,如图7.23所示。这样将会列出被StandardManager引用的全部对象。性能

图7.24显示了被StandardManager引用的对象,其中特别显眼的就是sessions对象,它占用了约17MB空间。优化

继续查找,打开sessions对象,查看被它引用的对象,如图7.25所示。能够看到sessions对象为ConcurrentHashMap,其内部分为16个Segment。从深堆大小看,每一个Segment都比较平均,大约为1MB,合计17MB。3d

继续打开Segment,查看存储在sessions中的真实对象。如图7.26所示,能够找到内部存放的为StandardSession对象。htm

 

7.3.5  Tomcat堆溢出分析(2)对象

经过OQL命令,查找全部的StardardSession,如图7.27所示(有关OQL,请参阅7.4节)。能够看到当前堆中含有9941个session,而且每个session的深堆为1592字节,合计约15MB,达到当前堆大小的50%。由此,能够知道,当前Tomcat发生内存溢出的缘由,很可能是因为在短时间内接收大量不一样客户端的请求,从而建立大量session致使。blog

为了得到更为精确的信息,能够查看每个session的内部数据,如图7.28所示,在左侧的对象属性表中,能够看到所选中的session的最后访问时间和建立时间。

经过OQL命令和MAT的排序功能,如图7.29所示,能够找到当前系统中最先建立的session和最后建立的session。再根据当前的session总数,能够计算每秒的平均压力为:9941/(1403324677648-1403324645728)*1000=311次/秒。

由此推断,在发生Tomcat堆溢出时,Tomcat在连续30秒的时间内,平均每秒接收了约311次不一样客户端的请求,建立了合计9941个session。

相关文章
相关标签/搜索