2012-04-03 14 views
13

Ho un'applicazione web in Tomcat 7.
quando chiudo Tomcat vedo questi avviso (ma non sempre)Quali sono questi avvisi in catalina.out?

SEVERE: The web application [/MyApplication] created a ThreadLocal 
with key of type 
[org.apache.xml.security.algorithms.MessageDigestAlgorithm$1] (value 
[[email protected]2e2c]) 
and a value of type [java.util.HashMap] (value 
[{http://www.w3.org/2000/09/xmldsig#sha1=MESSAGE DIGEST SHA-1}]) but 
failed to remove it when the web application was stopped. Threads are 
going to be renewed over time to try and avoid a probable memory leak. 
Apr 3, 2012 1:56:19 PM org.apache.catalina.loader.WebappClassLoader 
checkThreadLocalMapForLeaks SEVERE: The web application 
[/MyApplication] created a ThreadLocal with key of type 
[com.sun.xml.bind.v2.ClassFactory$1] (value 
[[email protected]]) and a value of type 
[java.util.WeakHashMap] (value [{class 
[email protected]b17eb, 
class 
javax.xml.bind.a[email protected]178a178a, 
class 
[email protected]1c181c, 
class 
c[email protected]17711771, 
class 
c[email protected]17011701}]) 
but failed to remove it when the web application was stopped. Threads 
are going to be renewed over time to try and avoid a probable memory 
leak. Apr 3, 2012 1:56:19 PM 
org.apache.catalina.loader.WebappClassLoader 
checkThreadLocalMapForLeaks SEVERE: The web application 
[/MyApplication] created a ThreadLocal with key of type 
[org.apache.xml.security.utils.UnsyncBufferedOutputStream$1] (value 
[[email protected]a90]) 
and a value of type [byte[]] (value [[[email protected]]) but failed to 
remove it when the web application was stopped. Threads are going to 
be renewed over time to try and avoid a probable memory leak. 

Cosa significano questi avvertimenti significano in catalina.out allo spegnimento?
vedo alcuni dei miei classi JAXB menzionati, ma non può dire qual è il problema qui.

Qualsiasi aiuto per favore?

risposta

23

In poche parole, alcuni ThreadLocals non sono state pulite adeguatamente. La maggior parte (se non tutti) i server J2EE/i contenitori delle applicazioni utilizzano i pool di thread per le richieste in entrata e altre attività, per evitare il sovraccarico di iniziare nuovi thread per tutto il tempo. Il problema è che alcune librerie (e tu stesso, se non conosci meglio) non ripuliscono i loro ThreadLocals dopo che l'esecuzione dell'attività/richiesta è terminata.

Normalmente, come il filo muore sull'estremità di esecuzione, gli oggetti memorizzati nella ThreadLocals non riferimento sono ed il collettore garbage prende cura di rimuovere tali oggetti:

Ogni filo contiene un implicito riferimento alla sua copia di un variabile locale dei thread finché il filo è vivo e l'istanza ThreadLocal è accessibile; dopo un filo va via, tutte le sue copie di casi thread-locali sono soggette a garbage collection (a meno che non esistano altre riferimenti a queste copie).

Ma quando il filo è stato prelevato da un pool di thread, non muore, ma invece viene restituito alla piscina. Poiché il thread è ancora attivo, lo sono anche i ThreadLocals di riferimento. Ciò si manifesta sia come perdite di memoria e "perdita" di valori da una richiesta a un'altra quando viene utilizzato lo stesso ThreadLocal e il thread che gestisce la richiesta/attività è stato utilizzato in precedenza.

+0

+ 1. Non uso thread locals nel mio codice. Come posso approfondire questo argomento? – Jim

+1

@Jim Vedere qui per il monitoraggio: http://tomcat.apache.org/tomcat-7.0-doc/monitoring.html, dopo aver abilitato il telecomando JMX, è possibile utilizzare ad esempio JConsole (fornito con JDK) per accedervi. I ThreadLocals sono probabilmente da una libreria che stai usando. Come ipotesi, dato che questi avvisi non appaiono sempre, è possibile che alcune librerie stessero facendo qualcosa quando si chiudeva l'applicazione, quindi Tomcat * poteva * dare falsi positivi. Se l'utilizzo della memoria dell'applicazione non continua a crescere nel tempo quando è in uso per periodi più lunghi e non si reimpiega spesso, non me ne preoccuperei più di tanto. – esaj

10

Almeno uno dei messaggi JAXB sembra riguardare un bug noto:

org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks GRAVI: L'applicazione web [/ MyApplication] ha creato un ThreadLocal con chiave di tipo [com.sun.xml.bind.v2.ClassFactory $ 1] (valore [[email protected]]) e un valore di tipo [java.util.WeakHashMap ]

Vedi JAXB-563 e JAXB-831 (NB - Questi sono su java.net e richiedono un accesso per visualizzare anche). Il primo bug era apparentemente risolto ma, come altri hanno commentato, questo non è stato completamente risolto. Il secondo bug presenta una soluzione alternativa che consiste nel forzare un gc() prima di consentire l'arresto del contesto che attenua il problema (sebbene non lo elimini del tutto): è possibile utilizzare uno ServletContextListener personalizzato e chiamare semplicemente System.gc() nel metodo contextDestroyed().

Per quanto riguarda gli altri errori è necessario seguire i consigli altre risposte e fare qualche seria debug.

+0

Man, questo sembra essere il mio problema, ma non posso avviare l'applicazione in Tomcat perché continua a darmi questo errore. Ho già modificato il web.xml con il nuovo ServletContextListener. Eventuali suggerimenti? –

+2

Ho riscontrato questo problema durante l'esecuzione di Jersey su Tomcat, con i driver Datastax Cassandra. Anche se ho chiuso la connessione del cluster Cassandra in contextDestroyed(), stavo ancora ricevendo gli errori di thread/perdita di memoria ogni volta che ho ridistribuito l'app. Aggiunta di System.gc() dopo che il cluster.close() si è occupato del problema. –

Problemi correlati