本文转自:http://www.blogjava.net/persister/archive/2010/01/14/309530.html
1、这家公司有一个数据库代理程序,用于数据库服务器的代理,游戏服务器执行sql指令,DBAgent接受此指令,执行一些组织后,调用JDBC执行数据库操作,然后将结果返回。
2、发生的问题:内存一直升高,处理客户端请求的线程并不多(高峰期大概300左右吧),数据库上的连接数也不多(100的样子)。运行5-6天,基本上内存就用完了,而且得不到数据库的连接。他们非常急,我就试着接下这个项目。
3、接到这个优化项目,查看了他们的部分代码。发现连接池写得有些问题,得不到数据库连接后wait,但是不会接到任何有效的notify,也就是说只要一等待就会超时。还有其他的问题,一开始我以为是这个问题,修改后让他们去跑,结果还是一样,内存上去后一直下不来,最后崩溃。
4、通过这个发现就是内存泄露了。一开始用jprofiler测试,发现内存上去后就Out of memory了,而且hashmap和long[]的对象非常多一直下不去。但是找不到这些对象是怎么产生的。折磨了我好几天,还请教了很多人,都得不到答案。后来发现是java启动参数中内存参数设置的太低了,本来需要100多M的内存,你就设置给16M,不崩溃才怪呢。于是改成了128M。结果内存上去之后,到达一个峰值就下来了,然后震荡,但一直就没有上去。那程序没有泄露?可是生产上怎么泄露了呢?
5、就在我基本上要放弃的时候,我想到了测试环境可能真实环境不同,有必要看一下他们生产服务器上虚拟机的运行情况。记得Java有自带的工具查询java虚拟机运行情况的。jmap这个工具可以查看jvm中运行实例的个数以及实例的类名。让他们的人用了下这个工具,将结果发给我了,我一看,吓了一大跳。排在第一位的是int[],竟然达到了1G。最有问题的是com.mysql.jdbc.PreparedStatement对象,达到了6万多。com.mysql.jdbc.ResultSetImpl和java.util.HashMap$Entry[]也达到了6万多。不用说,肯定是PreparedStatement没有关闭。
6、查看源代码,发现PreparedStatement对象都在finally块中关闭了,怎么会泄露呢?找了1个小时没有找到,就去洗澡了。在洗澡的时候突然想到,里面有一个for循环,PreparedStatement对象可能被赋值N次,那前面的N-1次不就没有关闭啊,对,找到答案了。赶紧擦干身子出来找到那段代码:
1 String[] valuesArray = value.split(";");
2 for (int i = 0 ;i < valuesArray.length;i++){
3
4 String[] valueArray = valuesArray[i].split(",");
10 ps = conn.prepareStatement(sqlbean.getSql());
11 for(int k = 0;k <valueArray.length;k++){
12 if("s".equalsIgnoreCase(paraTypeArray[k])){
13 ps.setString(k+1,valueArray[k]);
14 }else if("i".equalsIgnoreCase(paraTypeArray[k])){
15 ps.setInt(k+1,Integer.parseInt(valueArray[k]));
16 }
17 }
18
19 rsString = "" + ps.executeUpdate();
20
21 }
确实如此,循环的N-1个PreparedStatement对象没有关闭,导致了泄漏。解决办法就是将
ps = conn.prepareStatement(sqlbean.getSql());
移到for循环的外面,这样就没有问题了。不过从这段代码也可以看出,写得也是在是烂,这个干吗放到
循环的里面呢,本身从语言上来说就有问题。管它呢,解决问题就行了,呵呵。
几乎兴奋了一个晚上。第二天找他们的人一说,他们说是循环N次的,不只是一个值。问题不就解决了?Great。
7、让他们去测试运行吧。运行第一天的晚上九点(这是高峰期)以后,内存非常平稳。问题彻底解决了。
总结这次的优化项目:
对Java虚拟机的认识提高了。对java性能测试工具(JProfiler)更加熟练了,可以和eclipse集成呢,非常方便。
分享到:
相关推荐
多线程put的时候可能导致元素丢失 68 解决方案 68 【集合】ConcurrentHashMap的get(),put(),又是如何实现的?ConcurrentHashMap有哪些问题?ConcurrentHashMap的锁是读锁还是写锁? 69 【集合】HashMap与HashTable...
A 新增 多线程 worker 支持单步调试 A 新增 公众号网页调试中新增 url 收藏夹 A 新增 wx.compressImage 调试 A 新增 小游戏关系链互动数据开发支持 A 新增 支持小游戏 JSServer A 新增 小游戏节点审查插件 A ...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
8、修正“编码_Utf8到Unicode”频繁操作导致内存泄漏的BUG,感谢易友【◆野蛮vE儿】反馈。 9、修正“目录_是否存在”,当存在无反缀文件时返回真的BUG,感谢易友【@飞灵】反馈。 10、新增“系统_信息框Ex”定时信息...
与cgi的区别在于servlet处于服务器进程中,它通过多线程方式运行其service方法,一个实例可以服务于多个请求,并且其实例一般不会销毁,而CGI对每个请求都产生新的进程,服务完成后就销毁,所以效率上低于servlet。...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能,提供了图形界面和命令行两种操作方式,扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用服务漏洞、网络设备...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能。扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用服务漏洞、网络设备漏洞、拒绝服务漏洞等二十几个大类。对于...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
在全面了解了Windows的体系结构和程序运行方式后,我们将进一步介绍访问越界、缓冲溢出、内存泄露等故障的原理,并理论联系实际,带领大家使用调试工具来解决一些常见的问题。 深入研究Windows内部原理系列之十六...
功能简介: <br> 采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能,提供了图形界面和命令行两种操作方式,扫描内容包括:远程服务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用...
采用多线程方式对指定IP地址段(或单机)进行安全漏洞检测,支持插件功能。扫描内容包括:远程服 务类型、操作系统类型及版本,各种弱口令漏洞、后门、应用服务漏洞、网络设备漏洞、拒绝服务漏洞等 二十几个大类。...
修改外部数据库在4.12版中导致的不兼容问题,并增加了对MS SQL Server数据库中image和text字段类型的说明。 7. 修改扩展界面支持库一,禁止透明标签在父窗口刷新时自动刷新,以解决其导致窗口刷新缓冲的问题。 8....
测试可以帮助找到一些大型的问题,如死机、崩损、内存泄漏等,因为有些存在内存泄漏问题的程序,在运行一两次时可能不会出现问题,但是如果运行了成千上万次,内存泄漏得越来越多,就会导致系统崩滑。 Loadrunner...
简单地说,Java具有如下特点:简单的、面向对象、平台无关、多线程、分布式、安全、 晑性能、可靠的、解释型、自动垃圾回收等特点。 这里只解释一下平台无关和分布式,其余的在后面会逐步接触到 3:平台无关 所谓平台...