2010-12-02 4 views
5

Я пытаюсь поймать утечку памяти в одном из наших Java-демонов, а после сброса памяти и анализа ее с помощью Memory Analyzer Tool заметил, что большая часть утечки вызвана JDBC4Connection:Утечка памяти в 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, но не можем найти причину этого.

Есть ли хороший способ поймать его? Испытывали ли вы это в прошлом и можете посоветовать, что я должен искать?

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%

Кажется, каждый JDBC имеет огромное количество записей HashMap (> 6000 объектов), и не освобождает их вообще.

Заранее благодарен!

ответ

6

Duffymo почти наверняка правый. В прошлом, когда у нас были утечки памяти, это практически ВСЕГДА драйвер MySQL JDBC. Просто забудьте закрыть один маленький ResultSet или Connection или Statement где-нибудь. Я закончил аудит всей базы кода каждый раз, когда мы использовали их, чтобы найти проблему и убедиться, что они закрыты.

Что касается HashMap, я тоже это видел. Я не смотрел на источник, но мне показалось, что драйвер MySQL хранит строки (по крайней мере, значения строк) внутри HashMaps внутри.

Утечка ResultSets печально проста. Идея тех закрытых ресурсов, которые позаботились об этом самих, поступающих в JDK 7 или 8, действительно обращается ко мне по этой причине.

Вы можете вставить класс прокладки где-нибудь (скажем для подключения), чтобы регистрировать каждый открытый/закрытый ресурс, чтобы узнать, можете ли вы поймать, где протекает, без прямого чтения всего вашего источника.

+0

Немного наивный вопрос. но есть ли шанс, что это проблема в самом драйвере JDBC, и это поможет? Или это должно быть что-то строго в моем коде? – SyBer 2010-12-03 18:02:40

4

Я уверен, что мы закрыть все ресурсы MySQL

Если не 100% уверен, пожалуйста, покажите, как вы закрываете свои связи.

Вы используете пул соединений? Будет ли иметь размер пула 10?

+1

Да, мы используем бассейн BoneCP. – SyBer 2010-12-02 19:03:47