Как устранить утечки памяти прослушивателя качания?

StackOverflow https://stackoverflow.com/questions/1878127

Вопрос

Фон

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

Я знал, что наше приложение не отменяет регистрацию прослушивателей, и провел небольшое исследование потенциальных решений:

Я нашел один подход к решению проблемы - использование WeakReference, полную информацию о подходе с прослушивателями качания можно найти. здесь.

Затем мне стало любопытно, как NetBeans Редактор формы генерировал код для очистки после того, как прослушиватели добавили в форму и обнаружили, что NetBeans регистрирует прослушиватели через объект-оболочку, т.е.

argTypeComboBox.addItemListener(new java.awt.event.ItemListener() {
    public void itemStateChanged(java.awt.event.ItemEvent evt) {
      argTypeComboBoxItemStateChanged(evt);
    }
});

Но сгенерированный код, похоже, никогда не очищался при вызове removeItemListener.

Вопросы

Является ли объект-обертка слабой ссылкой?Мне кажется, что это может привести к утечке небольшого количества памяти (размера объекта-обертки)?

Есть ли у вас альтернативные подходы к работе со слушателями, чтобы гарантировать, что они всегда будут удалены сборщиком мусора, когда вы закончите с ними?

Это было полезно?

Решение

Сначала поправка, потенциальная утечка здесь немаленькая.Анонимный внутренний класс содержит ссылку на внешний класс, поэтому, пока прослушиватель доступен, он будет удерживать весь класс.

Однако обычно это не проблема, поскольку вы добавляете прослушиватели к объектам в кадре.Когда этот фрейм удаляется (хотя важно, чтобы он был удален) и больше не имеет ссылок (что довольно типично), все его компоненты становятся недоступными (если вы не сделали ничего необычного), и все это собирается мусором.

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

Таким образом, суть в том, что NetBeans не делает ничего, что могло бы привести к «утечкам» памяти, поскольку на компонент ссылается фрейм, а не за его пределами, и компонент ссылается на анонимный класс, который, в свою очередь, ссылается на фрейм — удалите фрейм. и весь граф недоступен, но нужно быть осторожным со слушателями, так как они могут сделать это с вами.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top