上Mysql com.mysql.jdbc.StatementImpl$CancelTask内存泄漏问题和解决方法
近来在负责公司短信网关的维护及建设,随着公司业务发展对短信依赖越来越严重了,短信每天发送量也比曾经每天40多w发送量暴增到每天达到200w发送量。由于是採用Java做发送底层,压力递增情况下不可避免的面对内存问题。
在发送量接近200w情况下,出现内存泄露问题了。
经过对系统执行检查发现:
1)每次重新启动系统3-4个小时后。均发现一点不稳定;
2)在3-4个小时后。出现out of memory的错误:java.lang.OutOfMemoryError: GC overhead limit exceeded
发现这个问题后,直接通过JMS获取监控日志,发现系统的内存回收存在异常,gc压力很大并且存在明显内存积压。
然后直接把系统的内存down下来分析,发现的确存在内存积压情况:
这个是mysql的一个定时任务的,这个定时任务主要作用是在用于做查询超时的。
简单举个样例,系统在运行一个sql查询情况下。jdbc会给你一个超时时间。为了保证超时时间后,能够关闭statement,会打开一个保护关闭的定时任务。假设超时情况下,sql还没响应运行,cancel task就会运行关闭任务。由于c3p0的默认设置的超时时间为25s(<setting name="defaultStatementTimeout" value="25000" />),意味这个25s内,在运行大量sql情况下。cancel task积压到了一定程度,就会造成系统不稳定。
(最后发现这个并非根本原因,仅仅是表象)
可是系统本身就有通过mysql做发送队列的,本身对mysql操作许多。假设仅仅是对代码层面下优化基本杯水车薪。
在时间紧迫的情况下。短时间内稳定业务才是最重要的任务。
被逼依据以上现状採用了暂时方案解决。
暂时方案
通过以上推断,基本能够判定cancel task在某组线程执行应该会形成一个峰值,撑爆了JVM的堆。可是如今无法在停止业务执行做过多调试,所以当机立断,对JVM的内存扩大一倍以上,希望系统能够跨过一波内存峰值。结果把JVM的内存调整为故障时候的2倍时候,系统的内存又恢复到正常运作。只是cancel task最高值会占用到内存2G以上。尽管也是会回收,可是一直扩内存不是非常好的办法。
解决方式
系统採用的mysql jdbc 5.1.6的版本号,立马反编译mysql代码,发现下面问题。
由于cancel task的timer在connection中静态存放。意味statement假设正常查询出结构,业务无法把cancel task内存回收才是故障根本原因。
明白问题在mysql jdbc上面后。根本解决的方法应该查询mysql jdbc是否攻克了这个bug。
在5.1.11版本号中找到这个bug的修复。更新后。内存泄漏故障得到解决。http://dev.mysql.com/doc/relnotes/connector-j/en/news-5-1-11.html
讨论并协助谢国波感和锐利康。使故障得以圆满解决!
相关文章
- MySQL实现字段自动计算的简单方法(mysql字段自动计算)
- 集的方法MySQL使用EXCEPT获取取差集的方法(mysql取差)
- 定义MySQL中查看函数定义的方法(mysql查看函数)
- MySQL数据库字段快速搜索方法(mysql字段搜索)
- MySQL查询:不等于的使用方法(mysql查询不等于)
- MySQL错误号解析:常见错误及其应对方法(mysql错误号)
- 轻松搞定:8G内存MySQL优化指南(8g内存mysql优化)
- MySQL工具revolution 给安卓带来的变革(mysql工具安卓)
- MySQL使用时间戳存储数据的巧妙方法(mysql存储时间戳)
- 掌握MySQL正版授权,把握企业数据未来(mysql 正版)
- MySQL分页存储:简单高效的数据处理方式(mysql存储分页)
- MySQL数据库的使用方法探索(mysql 数据库 使用)
- MySQL查询中非空值处理方法(mysql中不是null)
- MySQL中使用临时表的方法与应用(mysql中temp)
- MySQL中的性别字段应该用什么类型(mysql中sex用什么)
- C语言使用MySQL读取数据结果的方法(c mysql 读取结果)
- Mysql中使用in查询不成功的解决方法(mysql中in不起作用)
- MySQL批量插入C语言实现(c mysql批量插入)
- MySQL 严格模式的优先级详解(mysql严格模式优先级)
- MySQL 数据库解决两个键冲突问题(mysql两键冲突)
- 利用MySQL实现两行取差,简单高效的数据处理方法(mysql 两行取差)
- 从0基础学习CMD操作MySQL(cmd操作mysql教程)
- MySQL数据库的分数类型详解(mysql 三分数)
- 解决方法修复误删除或损坏的mysqlddll文件,确保MySQL数据库正常运行(mysql_d.dll)
- 轻松入门MySQL,不再愁不会用(mysql不会用)
- MySQL数据库中下划线处理方法详解(mysql 下划线处理)
- MySQL数据范围约束边界原则解析(mysql上下边界原则)