Come stampare eventi di garbage collection della classe java?


9
 
java version "1.5.0_14" 
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03) 
Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode) 

Sto tentando di eseguire il debug di una NullPointerException che sto ottenendo per il passaggio di un riferimento al campo statico. Per essere più specifico, sto impostando un globale su un'istanza di memoria di lavoro Drools3.

workingMemory.setGlobal("log", workingMemorieslog); 

Il mio presupposto è che la classe in cui il campo è definito staticamente è la raccolta di dati inutili. (La classe ricevente deve utilizzare WeakReference o qualcosa del genere, non lo so)

Come suggeriresti di eseguire il debug di questo? Penso che se potessi sapere esattamente quando GC di JVM scarica una classe/istanza di una classe, allora potrei restringere la causa del comportamento del buggy. (Se non è l'ora esatta dell'evento, almeno ricevendo un'indicazione che qualcosa è successo).

Grazie, Maxim.

  0

Buona domanda, buon seguito, buona risposta. +1 alla domanda e alla risposta. 22 feb. 092009-02-22 20:00:14

10

Per tracciare l'attività GC aggiungere questo al comando java:

-verbose: gc -XX: + PrintGCTimeStamps XX: + PrintGCDetails

NPE che hai trovato è probabilmente passare il valore nullo.

  0

Grazie per aver risposto, Sto già correndo con -XX: + PrintGCDetails -verbose: gc -Xnoclassgc e ancora non vedo alcuna informazione di caricamento/scaricamento della classe. L'unica uscita che ho sono righe come: [GC [PSYoungGen: 4096K-> 630K (4736K)] 4096K-> 790K (48064K), 0,0032750 sec.] 22 feb. 092009-02-22 00:27:12

  0

Poiché questa risposta si adatta al meglio all'argomento iniziale della domanda Lo accetto come risposta. Grazie. 22 feb. 092009-02-22 16:31:10


0

Avete la traccia dello stack?

Hai provato a passare al metodo "setGlobal" (supponendo che tu abbia il codice) per vedere cosa sta succedendo?


2

Perché non tenere la classe in memoria, quindi vedere se succede ancora, se lo fa, il problema si trova altrove. Altrimenti, sapete che il problema si trova nella raccolta dei rifiuti.


1

Si scopre che eclissi è il problema principale qui.

Mi spiego:

ho avvolto la nostra webapp in un metodo main() al fine di testare le prestazioni. Usiamo molto codice di terze parti, vale a dire Apache commons-pool.

Si è scoperto che avevamo diverse versioni del barattolo distribuite nei progetti (progetti di eclissi). La mia app che utilizza questi progetti aveva commons-pool-1.3, un progetto diverso aveva commons-pool-1.2.

Una volta caricato utilizzando il contenitore servlet (Tomcat6), il caricatore di classe webapp ha avuto la priorità, quindi ha sempre caricato la versione webapp. Quando ho avviato l'applicazione usando main() eclipse nel suo comportamento non molto saggio, ho esportato i jar dei progetti dipendenti in -classpath PRIMA di quelli nel progetto corrente.

Il conflitto era tra 2 versioni di commons-pool, che ha causato un comportamento non definito - Su un oggetto in prestito è SOMETIMES deciso di creare un nuovo oggetto. Non ho guardato all'interno del codice di implementazione, presumo che questo abbia a che fare con una mappa statica in attesa di GenericKeyedObjectPool (la classe problematica). Poiché è stata creata una nuova istanza, essa contiene effettivamente un riferimento null al suddetto globale.

La soluzione per mia fortuna era piuttosto semplice, commons-pool è utilizzato solo dal mio webapp così ho potuto eliminarlo da tutti i progetti di riferimento, altrimenti credo che vorrei solo provare a tutti loro l'aggiornamento a una versione singola.Se non potessi fare neanche io, davvero non so cosa avrei fatto. Questo è un insolito default di eclissi.

Grazie per aver letto e aiutato.

// ps. 3 giorni. Questo è il tempo che ho speso per capire cosa diavolo ho fatto di sbagliato nel mio codice di sostituzione servlet. Risulta che non sono nemmeno il problema. : P

+1

Nota: se hai problemi di riferimento agli oggetti, prova a registrare 'ProblemClass.class.getProtectionDomain(). GetCodeSource(). GetLocation(). AExternalForm()' Questo restituirà il jar o il file di classe da cui è stata caricata la classe . È un trucco inestimabile durante il debug delle applicazioni web, che spesso soffrono di problemi di classloader non deterministici. 02 gen. 132013-01-02 06:20:21