[java] утечка памяти
Если есть возможность использовать java 1.6 можно воспользоваться фичей eclipse 3.4 "what links here". Для нахождения утекших объектов можно использовать глобальный WeakHashMap. Либо найти профайлер который показывает графы объектов.
а можно как-то задампить всю информацию в текстовый файл, который потом на локальной машине в граф. интерфейсе просматривать?
Eclipse вроде поддерживает удаленную отладку (надеюсь приложение запускается из командной строки, а не каким-нибудь tomcat'ом но я ни разу не пробовал.
jmap -dump:format=b,file=heap.dump <pid>потом натравить на дамп хипа jhat
jhat.exe -J-mx512m heap.dumpЗайти броузером на 7000 порт и попробовать побродить по хипу. А вообще я б JProfiler взял, он конечно недешевый, но можно поюзать нелицензионный, если совесть позволит. Указываешь при запуске приложения на сервере использовать его profiling agent, а GUI запускаешь на рабочей станции и с комфортом разбираешься что да как.
спасибо. как-нибудь на досуге попробую разобраться.
- все ли JDBC-объекты закрываютя?
- в чем выражается утекание памяти, как ты проверял расход памяти
- пробовал ли смотреть verbosegc и что там с кучей происходит
Судя по дампу много резалтссетов и припейрд стейтментов. Так что ты прав видимо.
перевод данных из одной БД в другу с некоторой обработкойну если там есть большущая табличка
и ты ее сначала всю выбираешь в память а потом обрабатываешь то вот и будет огромный расход памяти
тойсть во-первых нада убедиться что ты эти данные целиком в памяти не держишь, тоесть выбрал часть обработал записал и отдал мусоросборщику
во-вторых надо понять как работает jdbc майскулевский, может там разные версии jdbc по-разному себя ведут, можно ли там вообще кэшем резалтсета управлять...
потом есть ли в базе длинные данные, типа CLOB/BLOB?
их надо и/о стримами обрабатывать а не выбирать все в огромный byte[]
профайлеры это конечно хорошо, но зачастую гораздо больше можно понять сделав логгирование основных операций
(в log4j TRACE в java logging FINEST)
типа: открыт резалтсет с id таким-то, закрыт резалтсет с id таким-то из него было выбрано столько то записей
- все ли JDBC-объекты закрываютя?
jdbc всего два, они постоянно используются
- в чем выражается утекание памяти, как ты проверял расход памяти
слежением за тем, что с памятью происходит во время работы. постоянный рост от 50 мб до 4ГБ с учетом свопа - я думаю очевидно, что это утечка. При алгоритме, который в цикле выполняет одни и те же операции и ничего в памяти (по идее) хранить не должен.
пробовал ли смотреть verbosegc и что там с кучей происходит
нет. попробую посмотреть.
Я нашел пост с вроде бы похожей проблемой. попробую сначала посмотреть в этом направлении. С драйвером работаю первый раз, поэтому вполне допускаю, что мог где-то чего-то по незнанию не закрыть, что требуется.
- все ли JDBC-объекты закрываютя?
jdbc всего два, они постоянно используются
Сутя по всему, ты подразумеваешь под JDBC объектами только Connection'ы. Закрывать надо также Statement'ы и ResultSet'ы
сервер, консоль, линуксА ты поставь на сервере хвинды, гном какой-нибудь и эклипсу, на своём компе xming и сиди в ней графически, лол.
надеюсь приложение запускается из командной строки, а не каким-нибудь tomcat'омесли в гугле набрать tomcat , то он сам продолжает: remote debug
и, что характерно, даёт ссылки на инструкции
Круто, не знал. И видимо не я один, раз народ постоянно спрашивает
Сутя по всему, ты подразумеваешь под JDBC объектами только Connection'ы. Закрывать надо также Statement'ы и ResultSet'ыуточню
когда закрываешь коннекшен, то все остальное автоматически закроется
стейтменты надо закрывать сразу после их использования, это понятно
а вот резалтсеты не надо закрывать вообще
они сами закрываются 1) если закрыть стейтмент (или коннекшен) 2) если в стейтменте открыть новый резалт сет
если этих двоих пунктов не происходит а резалт сет надо закрыть - то это ОЧЕНЬ странно
они сами закрываются 1) если закрыть стейтмент (или коннекшен) 2) если в стейтменте открыть новый резалт сетЭто в спецификации. Как ведет себя драйвер MySql - неизвестно.
ну можно же джаднуть и посмотреть
если этих двоих пунктов не происходит а резалт сет надо закрыть - то это ОЧЕНЬ странноCallableStatement.executeQuery в цикле с разными параметрами но одним и тем же запросом.
outParameter - курсор. На примере оракла - оно само не закрывается.
Думаю, еще полно примеров, когда резалтсет не будет закрыт при шаренном запросе в цикле.
а в спецификации точно есть пункт 2?
а в спецификации точно есть пункт 2?джавадок к резалтсету
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.а вот джавадок к стейтменту:
All execution methods in the Statement interface implicitly close a statment's current ResultSet object if an open one exists.но к препареду и коллаблу такого джавдока нет
и как бы {@inheritDoc} не стоит
тоесть реализация может чо угодно делать
Оставить комментарий
oleg1331
Java 1.5профилировщик jmp
Программа, которая по своей сути представляет собой перевод данных из одной БД в другу с некоторой обработкой. То есть в цикле однотипные операции.
Базы большие, но уже на 50.000 записей вся память утекает.
вот заголовок дампа jmp
То, что дальше - там совсем мелочи. То есть память отжирается где-то в при работе с мускулем. Кто-нибудь сталкивался с подобной проблемой, как решать и в каком направлении стоит смотреть?