Профилирование памяти для настольного Java-приложения
Мое приложение загружает набор данных ок. От 85 до 100 МБ каждый раз. Ограничение памяти приложения составляет 512 Мб, и этого, теоретически, более чем достаточно.
Тем не менее, я обнаружил, что если при однократном запуске приложения я открывал и закрывал набор данных 5 раз, общее потребление памяти неуклонно возрастало, пока не возникла ошибка нехватки памяти:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
6882 bguiz 20 0 679m 206m 19m S 30 13.7 0:30.22 java
6882 bguiz 20 0 679m 259m 19m S 9 17.2 0:55.53 java
6882 bguiz 20 0 679m 301m 19m S 9 20.0 1:20.04 java
6882 bguiz 20 0 679m 357m 19m S 33 23.7 1:44.74 java
6882 bguiz 20 0 679m 395m 19m S 80 26.2 2:10.31 java
Память выросла с ~ 14% до ~ 26%. Это похоже на утечку памяти.
Происходит то, что загружаемые данные верхнего уровня используются для заполнения коллекций, таких как карты и списки, а затем более подробные данные используются для создания подобъектов этих объектов верхнего уровня, а затем они, в свою очередь, создают подчиненные объекты. -SUB-объекты.
Когда набор данных закрыт, в настоящее время приложение действительно пытается очистить свои дорожки, удалив различные коллекции объектов, а затем явно вызвавSystem.gc();
Во всяком случае, это состояние приложения, когда я его получил (несколько лет находился в процессе разработки до меня), и мне было поручено это задание.
Что мне нужно сделать, так это найти способ найти, какие подчиненные объекты и подчиненные объекты все еще ссылаются друг на друга после выгрузки набора данных, и исправить их.
Очевидно, что это можно сделать вручную, но это будет очень и очень утомительно, но я чувствую, что было бы гораздо лучше сделать это с помощью профилирования памяти, чего я раньше не делал.
Я прочитал некоторые другие вопросы SO, в которых задавались вопросы о том, какие инструменты профилирования памяти использовать, и я решил использовать тот, который встроен в IDE Netbeans, поскольку он, похоже, имеет хорошие отзывы, и я все равно работаю в Netbeans.
Кто-нибудь занимался подобной задачей профилирования памяти Java раньше и задним числом:
Какой конкретный совет ты бы дал мне?Какие методы вы нашли полезными для решения этой проблемы?Какие ресурсы вы нашли полезными для решения этой проблемы?Изменить: Это приложение является стандартным настольным приложением, а не веб-приложением.
Редактировать: Внедренное решениеВ основном, для меня работало использование профилировщика Netbeans в сочетании с JHAT.
Я обнаружил, что Profiler, встроенный в IDE Netbeans, проделал действительно хорошую работу по созданию дампов памяти, в частноститочки профилированияи затем инструмент смог фильтровать и сортировать по классам и детализировать ссылки для каждого экземпляра. Что было действительно хорошо.
Однако он не дал мне возможности сравнить два дампа кучи. Я спросилответ на вопроси, похоже, JHAT (входит в JDK) справляется с этой работой достаточно хорошо.
Торбьерн Равн Андерсен, Дмитрий и Джейсон Гритман: ваш вклад был действительно полезным, к сожалению, я могу отметить только 1 как правильный ответ, и все вы все равно получили +1 от меня.