2009-12-10 9 views
9

TłoJak rozwiązać problemy z wyciekiem pamięci ze słuchacza?

Więc czytałem, że często wycieki pamięci w aplikacji Swing pochodzą z wykorzystaniem różnych słuchaczy (mysz, klucz, ostrość, etc). Zasadniczo, ponieważ rejestrujesz obiekt jako słuchacz i zapominasz wyrejestrować obiekt, powiadamiający kończy trzymanie się odniesienia obiektu i przecieka trochę pamięci.

Wiedziałem nasza aplikacja nie została wyrejestrowania słuchaczy i zrobiłem trochę badań na temat potencjalnych rozwiązań:

znalazłem jedno podejście w radzeniu sobie z problemem było stosowanie WeakReference, pełne informacje na temat podejścia z huśtawką słuchacze można znaleźć here.

I wtedy stał się ciekaw jak redaktor NetBeans forma została generowania kodu posprzątać po słuchacze dodany do formularza i odkrył, że NetBeans został rejestracji słuchaczy za pośrednictwem obiektu owijania tj

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

Ale wygenerowany kod nie nie wydaje się, aby kiedykolwiek oczyścić, dzwoniąc pod numer removeItemListener.

Pytania

Czy przedmiot owijania działa jak słaby odniesienia? Dla mnie wygląda na to, że może przeciekać niewielką ilość pamięci (rozmiar obiektu owijającego)?

Czy masz inne podejście do słuchania, aby upewnić się, że zawsze są one gromadzone podczas usuwania śmieci?

Odpowiedz

14

Najpierw korekta, potencjalny wyciek tutaj nie jest mały. Anonimowa klasa wewnętrzna zawiera odniesienie do klasy zewnętrznej, więc dopóki słuchacz jest osiągalny, zachowuje całą klasę.

Jednak zazwyczaj nie stanowi to problemu, ponieważ dodajesz detektory do obiektów w ramce. Kiedy ta ramka jest ułożona (ważne, aby ją usunąć) i nie ma już żadnych odniesień (co jest dość typowe), wszystkie jej składniki stają się nieosiągalne (jeśli nie zrobiłeś nic nadzwyczajnego) i cała rzecz zbiera śmieci.

Kiedyś miałem do czynienia z aplikacją, która jednak robiła wymyślne rzeczy, takie jak rejestrowanie otwartych okien z innym oknem, więc jeśli okno było zamknięte, to było jeszcze zarejestrowane - wielki wyciek pamięci - te okna nie były malutki.

Najważniejsze jest to, że NetBeans nie robi nic, aby spowodować "wycieki" pamięci, ponieważ komponent jest odwoływany przez ramkę, a nie poza nią, a komponent odwołuje się do anonimowej klasy, która z kolei odwołuje się do ramki - pozbyć się ramki, a cały wykres jest nieosiągalny, ale musisz uważać na słuchaczy, ponieważ mogą ci to zrobić.

+0

Świetne wyjaśnienie Yishai, jakie podejście podjąłeś w kontaktach ze słuchaczami w fantazyjnej aplikacji, która miała duży wyciek pamięci? – Clinton

+0

@ Clinton, kiedy zdiagnozowałem problem (który trochę potrwał, dużo profilowania), byłam pewna, że ​​wyrejestrowałem słuchacza z okna. Nie pamiętam wszystkich szczegółów, ale to był klucz - nie wiedziałem wtedy o słabych referencjach jako standardowym rozwiązaniu problemu, mogłem być w stanie to wykorzystać. – Yishai

+0

@ Yishai Robiłem wyrejestrowanie, kiedy słuchacz opuszczał lunetę ... Ale wydawało się, że jest trochę niezgrabny i szuka lepszego rozwiązania. Jeszcze raz dziękuję za korektę. – Clinton

Powiązane problemy