简体   繁体   English

JDBC4Connection中的内存泄漏

[英]Memory leak in 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: 我试图在我们的一个Java守护进程中捕获内存泄漏,在转储内存并通过Memory Analyzer Tool进行分析之后,注意到大部分泄漏是由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

I'm pretty sure that we closing all of the MySQL resources, but can't quite find what causing this. 我很确定我们关闭了所有的MySQL资源,但是找不到导致这种情况的原因。

Is there any good way to catch it? 抓住它有什么好办法吗? Have you experienced this in the past, and can advise what should I look for? 你有没有经历过这个,并建议我应该寻找什么?

PS: Looking deeper with MAT, I see the following info: PS:深入了解MAT,我看到以下信息:

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%

It seems as each JDBC holds a huge amount of Hashmap entries (>6000 objects), and does not free them at all. 似乎每个JDBC都拥有大量的Hashmap条目(> 6000个对象),并且根本不释放它们。

Thanks in advance! 提前致谢!

Duffymo is almost certainly right. 达夫莫几乎肯定是对的。 In the past when we've had memory leaks, it's practically ALWAYS the MySQL JDBC driver. 在过去,当我们有内存泄漏时,它实际上总是MySQL JDBC驱动程序。 Just forgetting to close one little ResultSet or Connection or Statement somewhere. 忘记在某处关闭一个小ResultSet或Connection或Statement。 I ended up auditing the entire codebase for every time we used those to find the problem and ensure they get closed. 每次我们使用它们来查找问题并确保它们关闭时,我最终都会审核整个代码库。

As for the HashMap, I've seen that too. 至于HashMap,我也看过了。 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. 我没有查看源代码,但我的印象是MySQL驱动程序在内部存储了HashMaps中的行(至少是行值)。

Leaking ResultSets is sadly easy. 泄漏的ResultSet很容易。 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. 由于这个原因,在JDK 7或8中自行处理这些可靠资源的想法确实吸引了我。

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. 您可以在某处插入一个垫片类(比如连接)来记录每个打开/关闭的资源,看看是否可以捕获泄漏的位置,而无需直接读取所有源。

I'm pretty sure that we closing all of the MySQL resources 我很确定我们关闭了所有的MySQL资源

If not 100% sure, please show how you're closing your connections. 如果不是100%确定,请说明您是如何关闭连接的。

Are you using a connection pool? 你在使用连接池吗? Would it happen to have a pool size of 10? 它的碰巧会有10个游泳池吗?

听起来你有一个连接池有10个连接,并且池启用了语句缓存,没有将缓存大小限制为健康数量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM