Мое приложение загружает набор данных ок. От 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%. Похоже, утечка памяти.
Что происходит, так это то, что загружаемые данные верхнего уровня используются для заполнения коллекций, таких как карты и списки, а затем более подробные данные используются для создания подобъектов этих объектов верхнего уровня, а затем они в включите создание суб-подобъектов.
Когда набор данных закрыт, в настоящее время приложение действительно пытается очистить свои дорожки путем удаления различных коллекций объектов, а затем явно вызывает System.gc();
Во всяком случае, это состояние приложения, когда я его получил (несколько лет находился в процессе разработки до меня), и мне было поручено это задание.
Что мне нужно сделать, так это найти способ выяснить, какие подобъекты и подобъекты все еще ссылаются друг на друга после выгрузки набора данных, и исправить их.
Очевидно, что это можно сделать вручную, но это будет очень и очень утомительно, но я чувствую, что было бы гораздо лучше сделать это с помощью профилирования памяти, чего я раньше не делал.
Я прочитал некоторые другие вопросы SO, в которых задавались вопросы о том, какие инструменты профилирования памяти использовать, и я решил использовать тот, который встроен в IDE Netbeans, поскольку он, похоже, имел хорошие отзывы, и я все равно работаю в Netbeans.
Кто-нибудь занимался подобной задачей профилирования памяти Java раньше и задним числом:
- Какой конкретный совет вы бы мне дали?
- Какие методы вы нашли полезными для решения этой проблемы?
- Какие ресурсы вы нашли полезными для решения этой проблемы?
Edit:
Это стандартное настольное приложение, а не веб-приложение.
Редактировать: Внедренное решение
В основном, для меня работало использование профилировщика Netbeans в сочетании с JHAT.
Я обнаружил, что Profiler, встроенный в IDE Netbeans, проделал действительно хорошую работу по созданию дампов памяти в определенных точках профилирования , а затем инструмент смог фильтровать и сортировать по классам и детализировать ссылки для каждого экземпляра. Что было действительно хорошо.
Однако он не дал мне возможности сравнить два дампа кучи. Я задал следующий вопрос , и похоже, что JHAT (входит в JDK) справляется с этой работой довольно хорошо.
Торбьерн Равн Андерсен, Дмитрий и Джейсон Гритман: ваш вклад был действительно полезным, к сожалению, я могу отметить только 1 как правильный ответ, и вы все равно получили +1 от меня.