Как найти утечку памяти Java - PullRequest
2 голосов
/ 26 января 2010

У меня проблема с утечкой памяти Java, которая по какой-то причине не отображается в моем профайлере (Yourkit). Когда я запускаю свое Java-приложение (сервер с несколькими потоками для прослушивания, отправки и обработки данных), кажется, что каждый раз, когда я получаю новое соединение, и это соединение удаляется, некоторая память не очищается. По крайней мере, так говорят Windows (и Linux).

Когда я запускаю свое приложение с помощью своего профилировщика, оно просто показывает память, какой она должна быть, когда поток закрывается, вся память очищается. Однако в действительности через некоторое время Java просто рухнул, потому что он использует слишком много памяти, поэтому независимо от того, что говорит мой профилировщик, я склонен полагать, что Windows и Linux используют его. Запуск сборки мусора также не очищает память.

Так что бы это могло быть? Я перепробовал все, что знаю, закрыл потоки, установил все объекты на нуль, удалил содержимое каждого массива и т. Д. Я почти уверен, что потоки закрыты, потому что и затмение, и компилятор, и распечатки, кажется, подтверждают это.

У кого-нибудь есть подсказка?

Ответы [ 5 ]

2 голосов
/ 26 января 2010

Вы можете попросить виртуальную машину создать дамп кучи при возникновении ошибки OutOfMemory, а затем проанализировать эту кучу.

Для Sun HotSpot VM вы можете запросить создание дампа кучи, как описано здесь .

Для анализа дампа вы можете использовать jVisualVM или jhat. (Могут быть и лучшие инструменты, но мне они пока не нужны.)

1 голос
/ 26 января 2010

Присоедините с помощью jvisualvm (в Java 6 JDK) и посмотрите, предоставляет ли он информацию (включая профилирование), которой нет в YourKit.

0 голосов
/ 26 января 2010

Существует другой ответ, который не связан с утечкой памяти и может вызвать сбой Java-процесса. Переполнение стека. Есть ли в ваших темах рекурсия? Есть ли способ, которым ваш код создает огромный стек вызовов? Вам необходимо опубликовать сообщение о сбое, чтобы мы могли отсеять различные возможности.

0 голосов
/ 26 января 2010

Вы можете попробовать просмотреть кучу - используйте jmap для создания двоичного дампа кучи, jhat запустит небольшой локальный сервер, который позволит вам просматривать содержимое кучи. Eclipse также имеет графический плагин, который позволяет вам просматривать кучу.

jmap -dump:format=b,file=FILENAME PID
jhat HEAPFILENAME

Это может быть не так уж и полезно, но это начало, например. если у вас огромные карты строк, куча, полная сотен тысяч строк, не скажет вам, какие карты и какие части кода являются нарушителями.

если вы создаете много потоков, вы также можете попробовать запустить jstack, который сообщит вам состояние всех потоков, которые в данный момент работают в вашем jvm.

0 голосов
/ 26 января 2010

Звучит так, будто вы что-то профилируете неправильно, возможно, вы что-то упускаете.

Профилировщик редко пропускает утечку, и она явно достаточно серьезна для сбоя вашего сервера. Вы проверили, что причина сбоя действительно связана с памятью?

Можете ли вы опубликовать подозрительную часть своего кода и некоторые результаты профилирования?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...