Как определить, когда освобождается память Java-объекта? - PullRequest
6 голосов
/ 11 августа 2010

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

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

Спасибо

Ответы [ 4 ]

6 голосов
/ 11 августа 2010

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

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

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

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

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

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

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

По сути, я использую PhantomReference в проекте, в котором кэш особого вида необходимо вычислять один раз при установке программного обеспечения. Для эффективного вычисления этого (дискового) кэша требуется гигантский объем памяти (чем больше, тем лучше). Я использую PhantomReference, чтобы отслеживать «почти точно», когда высвобождается этот гигантский объем памяти.

3 голосов
/ 11 августа 2010

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

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

Изменить:

Как указал 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/

1 голос
/ 11 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...