Как узнать, когда выпущена память объектов Java?

У меня есть приложение браузера Swing с ошибкой, так как я добавляю/удаляю в/из графического интерфейса, память не выделяется для этих объектов, и я пытаюсь отследить, что держится за них. Проблема в том, что я не знаю, как сказать, когда что-то действительно полностью освободилось из памяти.

Есть ли способ узнать, был ли объект выпущен из памяти? Я привык к Objective-C, где есть несколько способов сказать.

Спасибо

4 ответа

Вы не можете сделать это на Java. Все ответы, в которых упоминаются финализаторы, на самом деле не то, что вам нужно.

Лучшее, что вы можете сделать, это вставить PhantomReference в ReferenceQueue и опросить, пока вы не получите ссылку.

final ReferenceQueue rq = new ReferenceQueue();
final PhantomReference phantom = new PhantomReference( referenceToObjectYouWantToTrack, rq );

Вы хотите прочитать ответ Питера Кофлера здесь (он объясняет, что такое PhantomReference):

Вы когда-нибудь использовали ссылку Phantom в любом проекте?

Очень интересно читать здесь:

http://www.kdgregory.com/index.php?page=java.refobj

В принципе, я использую PhantomReference в проекте, где нужно вычислить очень специальный тип кеша, когда программное обеспечение установлено. Чтобы эффективно вычислить этот (на основе диска) кеш, требуется огромное количество памяти (тем лучше, тем лучше). Я использую PhantomReference для отслеживания "почти точно", когда освобождается этот гигантский объем памяти.


Edit:

Как отметил NoozNooz42, PhantomReference может делать все, что может сделать финализатор, без присутствия финализаторов проблем. Поэтому я рекомендую использовать PhantomReferences для расширения finalize(). Я сохраняю свой оригинальный пост в тактике, так как я думаю, что программисты Java должны хотя бы знать, что finalize() существует.

Оригинальное сообщение:

Каждый класс Java имеет метод finalize(), который запускается, когда никакие другие объекты не содержат ссылку на этот класс. Вы можете расширить этот метод следующим образом:

protected void finalize() throws Throwable {
 try {
 // Do whatever you want
 } finally {
 super.finalize();
 }
}

Таким образом, вы можете выяснить, имеет ли что-либо ссылку на объекты, о которых идет речь. Просто убедитесь, что вы всегда вызываете super.finalize(), если используете этот подход.

Ссылка на финализацию:

http://java.sun.com/developer/technicalArticles/javase/finalization/


Существует несколько способов обнаружения утечек памяти. Здесь три, о которых я сейчас думаю:

  • Прикрепление Profiler к вашему приложению (Netbeans или Eclipse TPTP должен быть полезен здесь)
  • Создание дампа кучи и анализ (с Eclipse Memory Analyzer), какие экземпляры класса хранятся в памяти, с помощью которых другие экземпляры.
  • Прикрепление VisualVM для отслеживания статуса коллекции мусора.


Попробуйте YourKit. Это профилировщик Java, который может показать вам использование вашей памяти и что происходит. IIRC, бесплатная пробная версия может интегрироваться с Eclipse и имеет все функции платной версии (у нее просто есть ограничение по времени).

licensed under cc by-sa 3.0 with attribution.