2009-12-10 9 views
9

SfondoCome risolvere le perdite di memoria del listener swing?

così ho letto che spesso perdite di memoria all'interno di applicazioni Swing provengono da l'uso di vari ascoltatori (mouse, tastiera, fuoco, ecc). Essenzialmente, poiché si registra un oggetto come ascoltatore e si dimentica di annullare la registrazione dell'oggetto, il notificatore finisce per trattenere il riferimento dell'oggetto e perde un po 'di memoria.

Sapevo che la nostra applicazione non è stata Annullamento della registrazione di ascoltatori e ha fatto un po 'di ricerca sulle possibili soluzioni:

ho trovato un approccio nell'affrontare il problema era l'uso di un WeakReference, tutti i dettagli sul metodo con swing gli ascoltatori possono essere trovati here.

Ho poi diventato curioso di sapere come l'editor NetBeans modulo stava generando codice per pulire dopo ascoltatori aggiunti alla forma e hanno scoperto che NetBeans registrava ascoltatori tramite un oggetto involucro cioè

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

Ma il codice generato ha fatto non sembra mai ripulire chiamando lo removeItemListener.

Domande

è l'oggetto di avvolgimento agisce come un riferimento debole? A me sembra che potrebbe perdere una piccola quantità di memoria (la dimensione dell'oggetto wrapping)?

Hai approcci alternativi quando hai a che fare con gli ascoltatori per assicurarti che siano sempre garbage collection quando hai finito con loro?

risposta

14

Prima di una correzione, la perdita potenziale qui non è minuscola. Una classe interiore anonima contiene un riferimento alla classe esterna, quindi finché l'ascoltatore è raggiungibile si manterrà su tutta la classe.

Tuttavia, questo in genere non è un problema, poiché si aggiungono gli ascoltatori agli oggetti su una cornice. Quando quel frame è disposto (importante che sia disposto, però) e non ha più riferimenti (che è piuttosto tipico), tutti i suoi componenti diventano irraggiungibili (se non hai fatto niente di fantasia) e tutto viene raccolto.

Una volta ho avuto a che fare con un'applicazione, ma ha fatto cose di fantasia, come la registrazione di finestre aperte con una finestra diversa, quindi se la finestra era chiusa, era ancora registrata - perdita di memoria di grandi dimensioni - queste finestre non erano molto piccolo.

Quindi la linea di fondo è che NetBeans non sta facendo nulla per causare "perdite" di memoria qui in quanto il componente è referenziato dal frame e non al di fuori di esso e il componente fa riferimento alla classe anonima, che a sua volta fa riferimento al frame - Disporre la cornice e l'intero grafico è irraggiungibile, ma devi stare attento con gli ascoltatori, in quanto possono farlo a voi.

+0

Grande chiarimento Yishai, qual è stato l'approccio che hai intrapreso per trattare con gli ascoltatori nella fantastica applicazione che ha avuto una perdita di memoria? – Clinton

+0

@Clinton, una volta diagnosticato il problema (che ha richiesto un po 'di tempo, un sacco di profilazione), ero sicuro di annullare la registrazione dell'ascoltatore sulla finestra. Non ricordo tutti i dettagli, ma quella era la chiave - non sapevo allora di riferimenti deboli come una soluzione standard al problema, avrei potuto essere in grado di usarlo. – Yishai

+0

@Yishai Avevo fatto il deregistration dato che l'ascoltatore stava lasciando il campo ... Ma sembrava un po 'goffo e andò alla ricerca di una soluzione migliore. Grazie ancora per la correzione. – Clinton

Problemi correlati