Ecco il corretto contenuto del mio file /META-INF/context.xml:
<Context>
<!-- Configuration for the Tomcat JDBC Connection Pool -->
<Resource name="jdbc/someDB"
type="javax.sql.DataSource"
auth="Container"
factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
driverClassName="org.postgresql.Driver"
url="jdbc:postgresql://localhost:5432/somedb"
username="postgres"
password="12345"
maxActive="100"
minIdle="10"
initialSize="10"
validationQuery="SELECT 1"
validationInterval="30000"
removeAbandoned="true"
removeAbandonedTimeout="60"
abandonWhenPercentageFull="50"
closeMethod="close" />
</Context>
Prestare attenzione all'attributo closeMethod. L'ho testato e ora il numero di connessioni viene mantenuto STRETTAMENTE come definito nel file contesto.xml!
NOTA
C'è un momento (relativi a JNDI) che può essere curato. Vedere l'AGGIORNAMENTO 3 per la descrizione completa.
Risposta lunga
OK, ho trovato la soluzione di cui sopra grazie a Apache Tomcat committor Konstantin Kolinko. Ho segnalato this issue come un bug Apache Tomcat su ASF Bugzilla e
si è scoperto che non è un bug
(vedi AGGIORNAMENTO 1).
=== UPDATE 1 (2012/12/03) alias "Una nuova speranza" ===
Beh, è ancora rivelato essere un bug .Mark Thomas, il release manager Apache Tomcat 7, confirmed che (cito):. PoolCleaner casi
"Questo è un bug perdita di memoria in JDBC-piscina sono ritegno riferimenti al ConnectionPool impedendone la GC'd
...
Questo è stato risolto nel trunk e 7.0.x e sarà incluso in 7.0.34 in poi. "
Quindi, se si dispone di una versione più vecchia di Tomcat (meno di 7.0.34), utilizzare la soluzione di cui sopra, in caso contrario,
iniziando con Apache Tomcat versione 7.0.34, non ci dovrebbero essere problemi, come quello che ho descritto.
(vedi UPDATE 2)
=== UPDATE 2 (2014/01/13) alias "Il problema colpisce ancora" ===
Sembra che il problema inizialmente descritto nel my bug report è ancora presente anche per l'attuale versione 7.0.50 di Apache Tomcat e l'ho riprodotta anche con Tomcat 7.0.47 (grazie a Miklos Krivan per averlo indicato). Sebbene ora Tomcat a volte riesca a chiudere le connessioni aggiuntive dopo il ricaricamento, ea volte il numero di connessioni aumenta dopo una ricarica e quindi viene mantenuto costante, ma alla fine questo comportamento non è ancora affidabile.
Ho ancora potuto riprodurre il problema inizialmente descritto (anche se non è ancora così facile: può essere correlato alla frequenza di ricariche successive). Sembra che sia solo una questione di tempo, ad esempio se Tomcat ha abbastanza tempo dopo la ricarica, gestisce il pool di connessioni più o meno come dovrebbe. Come ha detto Mark Thomas nel suo comment (citazione): "Come per i documenti per closeMethod, quel metodo esiste unicamente per accelerare la liberazione di risorse che altrimenti sarebbero state liberate da GC." (fine del preventivo), e sembra che la velocità sia il fattore determinante.
Quando si utilizza la soluzione presentata da Konstantin Kolinko (per utilizzare closeMethod = "close"), tutto funziona correttamente e il numero di connessioni riservate viene mantenuto STRETTAMENTE come definito nel file context.xml. Quindi sembra che l'uso di closeMethod = "close" sia l'UNICO modo vero (al momento) per evitare l'esaurimento delle connessioni dopo il ricaricamento del contesto.
=== UPDATE 3 (2014/01/13) aka "Il ritorno del Tomcat Release Manager" ===
il mistero dietro il comportamento descritto nella UPDATE 2 è risolto. Ulteriori dettagli sono stati cancellati ora dopo che ho ricevuto uno reply da Mark Thomas (Tomcat release manager). Spero che questo sia l'ultimo aggiornamento. Così il bug stato infatti fissato come è stato detto nella UPDATE 1. sto inviando la parte essenziale dalla risposta di Mark qui come una citazione (sottolineatura mia):
La perdita di memoria effettiva trovato mentre indaga questo bug ha stato risolto in 7.0.34 in poi come da commenti # 4 a # 6.
Il problema delle connessioni che non vengono chiuse durante il caricamento è il risultato di la specifica J2EE per risorse JNDI e questa parte del rapporto bug non è valida. Sto ripristinando lo stato di questo bug su corretto per riflettere che la perdita di memoria che esisteva è stata corretta.
Per espandere il motivo per cui la mancata chiusura immediata della connessione dopo il ricaricamento non è valida, la specifica J2EE non fornisce alcun meccanismo per il contenitore per indicare alla risorsa che non è più necessaria. Pertanto, tutto il contenitore può fare è chiaro riferimenti alla risorsa e attendere la garbage collection (che attiverà la chiusura del pool e le connessioni associate ). Garbage Collection si verifica a volte in base alla JVM quindi è necessario un intervallo di tempo indeterminato per le connessioni da chiudere dopo un aggiornamento del contesto poiché una raccolta di dati inutili non può verificarsi per qualche tempo.
Tomcat ha aggiunto l'attributo JNDI specifico Tomcat closeMethod che può essere utilizzato per attivare la chiusura esplicita di una risorsa JNDI quando viene arrestato un contesto . Se l'attesa per GC per pulire le risorse non è accettabile, utilizzare semplicemente questo parametro. Tomcat non utilizza questo per impostazione predefinita come , potrebbe avere effetti collaterali inaspettati e indesiderati per alcune risorse JNDI.
Se si desidera visualizzare un meccanismo standard fornito per comunicare alle risorse JNDI che non sono più necessarie, è necessario utilizzare il gruppo di esperti J2EE .
Conclusione
basta usare la soluzione presentata all'inizio di questo post (ma, nel caso, tenere a mente il problema relativo JNDI che possono teoricamente derivano da usarlo).
soluzione alternativa
Michael Osipov suggerito usando il suo CloseableResourceListener, che previene le perdite di memoria causati da risorse aperte sinistro durante undeployment delle applicazioni web. Quindi potresti anche provarlo.
NEGAZIONE
Gli alias per gli aggiornamenti sono stati ispirati dalla serie Star Wars film. Tutti i diritti appartengono ai rispettivi proprietari.
Molto probabilmente un duplicato di http://stackoverflow.com/questions/8435359/why-do-connections-persist-when-i-undeploy-a-webapp-using-the-tomcat-7-jdbc-conn – Isaac
@Isaac "È stato corretto da Tomcat 7.0.11", ma ho 7.0.32 e ho ancora lo stesso risultato. Quindi in pratica è un bug? – informatik01
Potrebbe essere una regressione. Se sei assolutamente sicuro che stai liberando tutte le connessioni e il problema persiste, ti chiederei di riaprire la segnalazione di bug. – Isaac