Java - анонимный жизненный цикл внутреннего класса - PullRequest
9 голосов
/ 20 января 2010

При использовании анонимного внутреннего класса в качестве PropertyChangeListener в какой момент жизненного цикла объекта собирается мусор класса? После того, как содержащий класс (SettingsNode) восстанавливается? Должен ли я явно удалить PropertyChangeListener в финализаторе содержащего класса (SettingsNode)?

public class SettingsNode extends AbstractNode
{
    public SettingsNode(Project project, ProjectSettings projectSettings)
        throws IntrospectionException
    {   
        // use an anonymous inner class to listen for changes
        projectSettings.addPropertyChangeListener(ProjectSettings.PROP_NAME,
            new PropertyChangeListener()
            {
                @Override
                public void propertyChange(PropertyChangeEvent evt)
                {
                   // handle event
                }
            });
     }
}

Ответы [ 5 ]

7 голосов
/ 20 января 2010

Как и все объекты, анонимный внутренний класс подходит для сбора мусора, когда последняя ссылка на него больше не ссылается на него. Здесь я использую ласку, потому что Java не гарантирует, что все будет GC'd & ndash; единственная гарантия - это не произойдет, пока есть ссылка.

В данном конкретном случае это будет, когда projectSettings либо делает removePropertyListener(), либо сам является сборщиком мусора.

Поскольку projectSettings ссылается на анонимный внутренний класс и поскольку внутренний класс ссылается на содержащий его класс, это означает, что содержащийся класс также будет жить по крайней мере столько же, сколько внутренний класс.

2 голосов
/ 20 января 2010

В примере, который вы показали, узел настроек и слушатель не могут быть восстановлены, пока не будут восстановлены настройки проекта.

Вам нужно будет явно удалить слушателя, но вам, вероятно, следует искать более надежное место, чем финализатор.

SettingsNode не будет восстановлен, пока не будет удален PropertyChangeListener. Использование анонимных классов для слушателей может быть распространенной причиной утечек памяти.

РЕДАКТИРОВАТЬ следующий вопрос от Алекса Б:

Если projectSettings существует в течение всего срока службы приложения, вы не можете удалить анонимного прослушивателя, поскольку у вас нет ссылки на него после его регистрации. По мере создания нескольких экземпляров SettingsNode они будут добавлять своих слушателей в конструктор, но они никогда не будут удалены, так как никто не имеет ссылки на них. Это остановит удаление узлов настроек, а также у слушателей есть ссылки на узлы настроек

2 голосов
/ 20 января 2010

Вы добавляете класс PropertyChangeListener, который вы создаете, в объект projectSettings. Этот PropertyChangeListener не будет собираться до тех пор, пока projectSettings ссылается на него.

1 голос
/ 07 августа 2012

Этот вопрос довольно устарел.

Однако я не согласен с большинством ответов здесь.

НЕТ необходимости явно удалять слушателя. В этом случае внутренний объект PropertyChangeListener класса будет жить до тех пор, пока не будет собрана сборка содержащего экземпляра SettingsNode.

На самом деле вы не можете удалить объект PropertyChangeListener, потому что для него нет ссылки.

Хотя верно, что объект PropertyChangeListener ссылается на содержащий его объект SettingsNode, это не препятствует разыменованию содержащего объекта и сборке мусора.

После разыменования содержащегося объекта все объекты, содержащиеся в узле SettingsNode, становятся «островком изоляции». Все они будут собирать мусор.

0 голосов
/ 18 марта 2010

Типичный сценарий утечки памяти. Не рекомендую завершать, так как это может задержать GC. Вы можете выставить функцию очистки или переопределить удаление и отмену регистрации.

Действительно удивлен, почему у свинга нет встроенной слабой регистрации слушателя. Возможно, вы могли бы попробовать какой-нибудь открытый исходный код в кузнице исходного кода?

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