加入收藏 | 设为首页 | 会员中心 | 我要投稿 温州站长网 (https://www.0577zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长资讯 > 外闻 > 正文

值得阅读的内存泄露分析总结和Tomcat调优

发布时间:2019-02-28 19:14:11 所属栏目:外闻 来源:今日头条
导读:副标题#e# 写在最前面,运行环境:tomcat8,jdk1.8,windows server 2008内存16G,软件LoadRunner11,MAT和JProfile9.1。 问题描述:前段时间遇到一个很奇怪的问题,开发的WEB应用,经常会毫无症状的宕掉,然后抓了线程栈看下,发现之前写的数据库链接池出

这个看名字就知道是用来检测是否存在内存泄露的,后面看到Tomcat管理页面自带一个Find Leaks的功能,不知道是不是和这个有关系。然后我进这个类看了下就有了新发现,在这个类里面我看到GC日志里面执行system.gc的那个类名!看下图:

这里这个gcDaemonProtection的参数在这个类的上面已经定义了,默认是true。这就意味着如果不手动修改配置文件,肯定会进这个判断。里面用反射调用了sun.misc.GC的requestLatency方法。我点进这个sun.misc.GC类里面,看到了GC日志里面那个run的地方,看下图:

看名字这是一个守护进程,里面调用了system.gc(),这下可以肯定的是GC日志里频繁出现的Full GC操作就是这里引起的(后面我又抓了很多次线程栈发现调用GC的只有这一个类)。到这里我终于可以确定为什么GC日志里面那么多Full GC了,都是因为Tomcat配置里面加载这个内存检测的Class导致的。那有什么办法可以避免这个呢,后来网上查了下,有这么几种方法:

① 直接去掉这个配置

② 将上面那个默认配置true的参数改成false,将Server.xml里面的对应那条配置中增加下面的一段:

  1. gcDaemonProtection=”false” 

③ 增加-XX:+ExplicitGCInvokesConcurrent配置,这个参数不会像DisableExplicitGC一样强行忽略手动调用system.gc,而是在遇到调用system.gc时调用CMS垃圾回收方法。因为上面提过CMS是停顿最短的GC方法,这样就可以避免由full

GC带来的长GC pause引起的性能问题。

经过测试我是采用的第三个方法,到最后内存增长的问题得到了解决。最后我们看一下GC日志中CMS的耗时,看下图:

值得阅读的内存泄露分析总结和Tomcat调优

这里被我用红线划得就是mark和remark的两个阶段,因为这有这两个阶段是Stop-the-world的,可以看到耗时和Full GC比起来要短很多。

最后Tomcat的JVM配置参数被我修改为下图:

值得阅读的内存泄露分析总结和Tomcat调优

这里面有几个比较重要好用的我大概说一下:

-Xloggc:gc.log -XX:+PrintGCDetails,这个参数会设置打印GC日志,这次问题,靠GC日志分析出了很多有用的东西。

-XX:+UseConcMarkSweepGC ,选用CMS作为垃圾回收方法

-XX:+ ExplicitGCInvokesConcurrent,用这个替换了DisableExplicitGC,每次遇到system.gc时调用一次CMS回收,并不是直接Stop-the-world。

-XX:+UseCMSCompactAtFullCollection,在每次CMS收集器在完成垃圾回收之后做一次内存碎片整理。

Tomcat的线程池也是可以自己配置的,包括可接受的连接数之类的,这里我就不展开说了,码字也不轻松…

其他还有很多有兴趣的可以自行了解。

总结

(编辑:温州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读