Я хочу найти утечки памяти в моем приложении java, но я не знаю, как использовать профилировщик Netbeans для этого.
Ответ 2
Настроить
Поскольку некоторые из приведенных здесь ссылок несколько устарели и предназначены для NetBeans 6.0, ниже приводится небольшое обновление для устранения утечек памяти в настольных приложениях Java с использованием Netbeans 6.8.
Для начала вам нужно выполнить широкий поиск вашего приложения, чтобы найти, какие общие области/функции могут быть утечки памяти. Поэтому запустите профилировщик NetBeans, выбрав:
Профиль → Профиль проекта (название проекта)
Затем настройте свой профилировщик следующим образом:
![mem setup]()
Широкий поиск
Таким образом, вы можете видеть, когда происходит утечка памяти, и чтобы помочь при поиске, откройте обзор телеметрии (помеченный как A на рисунке ниже).
При выполнении широких поисков вы хотите продолжать выполнять несколько шагов, которые переводят ваше приложение из одного цикла в другое, обратно в исходное "чистое" состояние. В моем случае я в значительной степени вставил некоторые данные в свое приложение (file-> open), отобразил их (показать) и затем очистил все (file-> new). После того, как я сделал file-> new, я ожидал, что использованная куча и число оставшихся в живых поколений будут такими же, как и при запуске... Если они по-прежнему высоки после запуска сборщика мусора, вы вытекли немного памяти,
![alt text]()
Сужение поиска
Теперь, когда вы нашли в своем приложении функцию, которая приводит к утечке памяти, пришло время сузить поиск и точно определить, на какие объекты все еще ссылаются. Это делается в профилировщике NetBeans путем получения "дампов кучи":
Профиль → Возьми дамп кучи...
Это вызовет кучу на сводной странице, переключится на представление классов и отфильтрует классы ваших проектов, введя имя корневого пакета, например: org.yourproject, отсортировав его по Instances [%], и вы получите объекты, которые потребляют большая память:
![alt text]()
Теперь запустите шаги туда и обратно, которые, как вы обнаружили, протекают во время широкого поиска, и сделайте еще один дамп кучи:
Профиль → Возьми дамп кучи...
Сравнивая два списка, найдите классы, у которых больше экземпляров во втором дампе, чем в первом. Классы с большим количеством экземпляров могут быть утекшими в памяти. Во втором файле дампа дважды щелкните класс, который может быть утечкой, чтобы вызвать его в представлении экземпляров:
Внизу слева находятся все экземпляры определенного класса, по которому вы дважды щелкнули, и если вы выберете один из них, его поля и ссылки будут заполнены справа. Поскольку мы подозреваем, что этот объект может протекать, что-то должно содержать ссылку на него. Щелкните правой кнопкой мыши "this" в списке ссылок и выберите "Show Nearest GC Root". Если диалоговое окно возвращается с "Корнем GC не найден", это означает, что виртуальная машина Java будет собирать мусор в следующий раз, и объект не отвечает за утечку памяти. Однако, если дерево расширяется, то это может быть одним из протекающих преступников.
![alt text]()
Ключом к этому шагу является работа сверху вниз по списку. На изображении выше IntDataValue - это объект, который, по нашему мнению, протекает, и следующая вещь в дереве - это объект, который на него ссылается. Поле - это переменная, которая содержит ссылку, а тип - это тип объекта, который ее содержит. Работая вниз по списку, продолжайте переходить к исходному коду и задавайте себе следующие вопросы:
Почему это держит ссылку?
Должен ли он содержать ссылку?
Идя по дереву, задавая себе эти вопросы, я часто обнаруживаю, что запуск отладчика и пошаговое выполнение кода - единственный способ найти ответы.
ОБНОВЛЕНИЕ: Помощь в сужении поиска
Выше приведен оригинальный механизм, который я использовал для сужения поиска, но я нашел другой способ помочь сузить поиск, используя функцию "Compre memory snapshot..." в меню "Профиль". Сначала сделайте снимок (см. Скриншот).
![alt text]()
Теперь выполните шаги туда и обратно, которые, как вы обнаружили, протекают во время широкого поиска, и сделайте еще один снимок. Сохраните их где-нибудь, чтобы найти их с помощью кнопки "Сохранить как...".
Выберите Профиль → Сравнить снимок памяти...
Выберите два снимка, стараясь поместить первый снимок в верхний слот, а второй снимок - в нижний слот (в противном случае вы получите неправильные отрицательные изменения памяти):
![alt text]()
Это создаст экран, подобный следующему, где число байтов - это размер изменения в распределениях между двумя моментальными снимками (т.е. Большие увеличения могут вызывать утечки памяти вместе с изменением количества выделений):
![alt text]()