Утечка памяти в JDBC4Connection - PullRequest
       25

Утечка памяти в JDBC4Connection

5 голосов
/ 02 декабря 2010

Я пытаюсь обнаружить утечку памяти в одном из наших демонов 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

Я почти уверен, что мы закрываем все ресурсы MySQL, но не могу найти причину этого.

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

P.S .: Глядя глубже с 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 объектов) и не освобождает их вообще.

Заранее спасибо!

Ответы [ 2 ]

6 голосов
/ 02 декабря 2010

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

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

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

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

4 голосов
/ 02 декабря 2010

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

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

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

...