Стратегии диагностики проблем с памятью Java

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

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

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

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
4
0
3 672
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

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

Спасибо за внимание. Примерно через 30 минут, потраченных на настройку интеграции профилировщика, я смог найти источник утечки памяти примерно за 5 минут. Оцените предложение.

Matty 07.01.2009 19:24

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

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

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

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

Я хотел бы дать прямую ссылку на мой комментарий о EMA в другом потоке, но я не могу рекомендовать это достаточно. EMA может открыть файл журнала дампа кучи размером ~ 400 МБ менее чем за 5 минут для меня, в то время как jhat потребовалось более 70 минут, чтобы прочитать его, прежде чем он разбил JVM (никогда не мог даже открыть его полностью).

matt b 18.06.2009 22:39

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

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

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

Другие вопросы по теме