JDBC4Connection中的内存泄漏 [英] Memory leak in JDBC4Connection

查看:328
本文介绍了JDBC4Connection中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我们的一个Java守护程序中捕获内存泄漏,并且在转储内存并通过Memory Analyzer Tool分析它之后,注意到大部分泄漏是由JDBC4Connection引起的:

I'm trying to catch a memory leak in one of our Java daemons, and after dumping the memory and analyzing it via Memory Analyzer Tool, noticed that most of the leak is caused by the JDBC4Connection:

10 instances of "com.mysql.jdbc.JDBC4Connection", loaded by "sun.misc.Launcher$AppClassLoader @ 0x2aaab620ed00" occupy 858,283,752 (81.55%) bytes. Biggest instances:

* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64ad820 - 87,110,160 (8.28%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64af520 - 86,730,408 (8.24%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64ad0e0 - 86,584,048 (8.23%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64aede0 - 86,488,800 (8.22%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab61f5320 - 85,752,872 (8.15%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64ae6a0 - 85,603,280 (8.13%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64adf60 - 85,270,440 (8.10%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab61f4be0 - 85,248,592 (8.10%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab64afc60 - 85,120,704 (8.09%) bytes.
* com.mysql.jdbc.JDBC4Connection @ 0x2aaab61f5a60 - 84,374,448 (8.02%) bytes.

Keywords
com.mysql.jdbc.JDBC4Connection
sun.misc.Launcher$AppClassLoader @ 0x2aaab620ed00

我很确定我们关闭了所有MySQL资源,但是找不到导致此问题的原因.

I'm pretty sure that we closing all of the MySQL resources, but can't quite find what causing this.

有什么好的方法可以捕捉到它吗?您过去有过这种经历,可以建议我寻找什么吗?

Is there any good way to catch it? Have you experienced this in the past, and can advise what should I look for?

P.S .: 深入了解MAT,我看到以下信息:

P.S.: Looking deeper with MAT, I see the following info:

com.mysql.jdbc.JDBC4Connection @ 0x2aaab64ad820 | 1,856 | 87,110,160 | 8.28% |- java.util.HashMap @ 0x2aaab62115a8 | 64 | 87,021,632 | 8.27% | '- java.util.HashMap$Entry[16384] @ 0x2aaae182e970| 131,096 | 87,021,568 | 8.27%

com.mysql.jdbc.JDBC4Connection @ 0x2aaab64ad820 | 1,856 | 87,110,160 | 8.28% |- java.util.HashMap @ 0x2aaab62115a8 | 64 | 87,021,632 | 8.27% | '- java.util.HashMap$Entry[16384] @ 0x2aaae182e970| 131,096 | 87,021,568 | 8.27%

似乎每个JDBC都拥有大量的Hashmap条目(> 6000个对象),并且根本不释放它们.

It seems as each JDBC holds a huge amount of Hashmap entries (>6000 objects), and does not free them at all.

提前谢谢!

推荐答案

Duffymo几乎可以肯定是正确的.在过去,当我们发生内存泄漏时,实际上总是使用MySQL JDBC驱动程序.只是忘记在某个地方关闭一个小的ResultSet或Connection或Statement.每当我们使用那些代码库来发现问题并确保它们被关闭时,我最终都要审核整个代码库.

Duffymo is almost certainly right. In the past when we've had memory leaks, it's practically ALWAYS the MySQL JDBC driver. Just forgetting to close one little ResultSet or Connection or Statement somewhere. I ended up auditing the entire codebase for every time we used those to find the problem and ensure they get closed.

关于HashMap,我也看到了.我没有查看源代码,但给我的印象是MySQL驱动程序在内部将行(至少是行值)存储在HashMaps中.

As for the HashMap, I've seen that too. I haven't looked at the source but my impression was that the MySQL driver stored the rows (at least row values) in HashMaps internally.

泄漏ResultSet很容易.出于这个原因,在JDK 7或8中引入那些可以自行处理的可关闭资源的想法真的吸引了我.

Leaking ResultSets is sadly easy. The idea of those closeable resources that take care of this themselves coming in JDK 7 or 8 really appeals to me for this reason.

您可以在某个位置插入一个shim类(例如Connection)来记录每个打开/关闭的资源,以查看是否可以在不直接读取所有源代码的情况下发现泄漏的位置.

You could insert a shim class somewhere (say for Connection) to log each opened/closed resource to see if you can catch where the leak is without directly reading all your source.

这篇关于JDBC4Connection中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆