2011-12-02 18 views
51

Ho eseguito un dump dell'heap sul mio programma. Quando l'ho aperto nello strumento di analisi della memoria, ho scoperto che lo java.lang.ref.Finalizer per org.logicalcobwebs.proxool.ProxyStatement occupava molta memoria. Perché è così?c'è una perdita di memoria? perché java.lang.ref.Finalizer mangia così tanta memoria

screenshot

+0

Il collegamento "immagini" va a quello che sembra essere il tuo profilo twitter. –

+0

@ R.MartinhoFernandes Passa a un'immagine che ha ospitato su Twitter, penso. – Oliver

risposta

49

Alcune classi implementano il metodo Object.finalize(). Gli oggetti che eseguono l'override di questo metodo devono essere richiamati da un finalizzatore di chiamata thread in background e non possono essere eliminati fino a quando ciò non avviene. Se queste attività sono brevi e non si scartano molte di queste, tutto funziona bene. Tuttavia, se si creano molti di questi oggetti e/o i loro finalizzatori richiedono molto tempo, la coda degli oggetti da finalizzare si accumula. È possibile che questa coda utilizzi tutta la memoria.

La soluzione è

  • non utilizzare finalizzazione (d) gli oggetti se si può (se si sta scrivendo la classe per l'oggetto)
  • fare finalizzare molto breve (se si dispone di usarlo)
  • non gettare tali oggetti ogni volta (prova riutilizzarle a)

L'ultima opzione è probabile che sia meglio per voi come si sta utilizzando una libreria esistente.

+12

Opzione 4: evitare l'uso di librerie che (sopra) utilizzano i finalizzatori. –

+3

Una variante dell'opzione n. 1;) –

+0

forse il problema è la causa del thread di Finalizer. una classe sovrascrive il methond finalizzato, causa il deadlock del thread Finalizer – fuyou001

7

Da quello che riesco a capire, Proxool è un pool di connessioni per connessioni JDBC. Questo mi suggerisce che il problema è che la tua applicazione sta usando male il pool di connessioni. Invece di chiamare close sugli oggetti istruzione, è probabile che il codice li stacchi e/o le loro connessioni padre. Il Proxool si basa sui finalizzatori per chiudere gli oggetti implementati dal driver sottostante ... ma ciò richiede quelle istanze di Finalizer. Potrebbe anche significare che stai causando la connessione per aprire/chiudere connessioni (reali) al database più frequentemente del necessario, e che sarebbe un male per le prestazioni.

Quindi suggerisco di controllare il codice per gli oggetti ResultSet, Statement e/o Connection trapelati e assicurarsi di chiuderli nei blocchi finally.


Guardando il dump della memoria, mi aspetto siete preoccupati dove i 898,527,228 byte stanno andando. La stragrande maggioranza viene mantenuta dall'oggetto Finalizer il cui id è 2aab07855e38. Se hai ancora il file di dump, dai uno sguardo a cosa a cui si riferisceFinalizer. Sembra più problematico degli oggetti Proxool.

+0

grazie, ma non riesco a trovare la causa della perdita di memoy poll di connessione JDBC – fuyou001

+0

Beh, non posso neanche a meno che non vedo il tuo codice sorgente. (E non sono disposto a passare il mio tempo a trascinarlo comunque ...) –

Problemi correlati