Стратегии диагностики проблем памяти Java - PullRequest
4 голосов
/ 07 января 2009

Мне было поручено отладить приложение Java (J2SE), которое после некоторого периода активности начинает генерировать исключения OutOfMemory. Я новичок в Java, но у меня есть опыт программирования. Мне интересно узнать ваше мнение о том, каким может быть хороший подход к диагностике такой проблемы?

Пока я использовал JConsole, чтобы получить представление о том, что происходит. У меня есть догадка, что есть объект, который не освобождается должным образом и поэтому не очищается во время сбора мусора.

Могу ли я использовать какие-либо инструменты, чтобы получить представление об экосистеме объекта? С чего бы начать?

Ответы [ 5 ]

4 голосов
/ 07 января 2009

Попробуйте Eclipse Memory Analyzer или любой другой инструмент, который может обработать дамп кучи Java, а затем запустите ваше приложение с клапаном, который генерирует дамп кучи при исчерпании памяти.

Затем проанализируйте дамп кучи и найдите подозрительно большое количество объектов.

См. Эту статью для получения дополнительной информации о дамп кучи .

РЕДАКТИРОВАТЬ: Кроме того, обратите внимание, что вашему приложению на законных основаниях может потребоваться больше памяти, чем вы первоначально думали. Вы можете сначала попытаться увеличить минимальное и максимальное выделение памяти java до чего-то значительно большего и посмотреть, работает ли ваше приложение бесконечно или просто идет немного дальше.

4 голосов
/ 07 января 2009

Я бы начал с правильного профилировщика Java. JConsole бесплатен, но он еще не настолько полнофункциональный, как тот, который стоит денег Я использовал JProfiler, и он того стоил. См. https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler для дополнительных опций и мнений.

2 голосов
/ 07 января 2009

Последняя версия Sun JDK включает VisualVM, который сам по себе является профилировщиком Netbeans. Это работает очень хорошо.

1 голос
/ 07 января 2009

http://www.yourkit.com/download/index.jsp - единственный инструмент, который вам понадобится. Вы можете делать снимки во время (1) запуска приложения и (2) после запуска приложения в течение N промежутков времени, затем сравнивая снимки, чтобы увидеть, где выделяется память. Он также сделает снимок на OutOfMemoryError, чтобы вы могли сравнить этот снимок с (1).

Например, последний проект, который мне пришлось устранить, вызвал исключения OutOfMemoryError, и после запуска YourKit я понял, что большая часть памяти фактически была выделена для некоторого класса ehcache "LFU", суть в том, что мы указали загрузки определенного POJO будет кэшироваться в памяти, но мы не указали достаточно -Xms и -Xmx (начальная и максимальная JVM-память).

Я также использовал Linux vmstat , например. некоторые платформы Linux просто не имеют достаточного количества подкачки или не выделяют смежные блоки памяти, и есть jstat (в комплекте с JDK).

ОБНОВЛЕНИЕ см. https://stackoverflow.com/questions/14762/please-recommend-a-java-profiler

0 голосов
/ 07 января 2009

Вы также можете добавить «UnhandledExceptionHandler» в ветку вашего приложения. Это будет перехватывать «неперехваченное» исключение, например, ошибка нехватки памяти, и вы, по крайней мере, будете иметь представление, где было сгенерировано исключение. Обычно это не та проблема, а «новое», которое не может быть удовлетворено. Как правило, я всегда добавляю UnhandledExceptionHandler в поток, если больше нечего добавить в журнал.

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