2010-08-19 17 views
21

SembraTomcat sul server di produzione, PermGen e riutilizza

MemoryError: PermGen space 
java.lang.OutOfMemoryError: PermGen space 

è un problema comune. Puoi aumentare la dimensione del tuo spazio perm, ma dopo 100 o 200 redeploys sarà pieno. Tenere traccia delle perdite di memoria di ClassLoader è quasi impossibile.

Quali sono i metodi per Tomcat (o un altro contenitore di servlet semplice - Jetty?) Sul server di produzione? Il riavvio del server dopo ogni distribuzione di una soluzione?

Usi un Tomcat per molte applicazioni?

Forse dovrei usare molti server Jetty su porte diverse (o un Jetty incorporato) e annullare la distribuzione/riavvio/distribuzione ogni volta?

+0

hai provato ad aumentare le dimensioni dell'heap? – vsingh

+0

Non è un problema con le dimensioni dell'heap, ma genera un problema di scarico bytecode delle classi. Dicono che le classi non vengono scaricate in JVM e lo spazio PermGen non viene spazzato. –

risposta

6

Ho rinunciato a utilizzare il gestore tomcat e ora lo shutdown di Tomcat per ridistribuire.

Noi usiamo due Tomcats sullo stesso server e utilizzare webserver apache con mod_proxy_ajp così gli utenti possono accedere a entrambe le applicazioni tramite la stessa porta 80. Questo è bello anche perché gli utenti vedono la pagina non disponibile Apache servizio quando il gatto è giù.

+1

Utilizziamo due tomc su diverse porte dietro HAProxy per fornire una soluzione di distribuzione blu-verde. Il server "blu" viene spento quando "Verde" è attivo e funzionante, HAProxy passa quindi a "Verde". La prossima distribuzione va quindi a "Blu". –

2

Sì, certo, questo è un problema. Stiamo eseguendo tre app Web su un server Tomcat: No. 1 utilizza un framework per applicazioni web, Hibernate e molti altri JAR, no. 2 usa Hibernate e alcuni JAR e no. 3 è fondamentalmente un'applicazione JSP molto semplice.

Quando distribuiamo no. 1, riavviamo sempre Tomcat. In caso contrario, un errore di spazio PermGen ci morderà presto. No. 2 a volte può essere distribuito senza problemi, ma dal momento che cambia spesso quando no. 1 fa pure, un riavvio è programmato comunque. No. 3 non pone alcun problema e può essere distribuito tutte le volte che è necessario senza problemi.

Quindi, sì, in genere riavviamo Tomcat. Ma attendiamo con impazienza anche Tomcat 7, che dovrebbe gestire molti problemi di caricamento della memoria/classe che vengono nascosti in diversi JAR e framework di terze parti.

3

Si può provare ad aggiungere queste opzioni Java:

-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled 

Ciò consente la raccolta dei rifiuti nello spazio PermGen (disattivata per default) e consente al GC per scaricare le classi. Inoltre, è necessario utilizzare -XX: PermSize = 64m -XX: MaxPermSize = 128m menzionato altrove per aumentare la quantità di PermGen disponibile.

+2

Come si suppone possano aiutare? – vsingh

1

È necessario abilitare la garbage collection di PermGen. Per impostazione predefinita, Hotspot VM NON raccoglie spazzatura PermGen, il che significa che tutti i file di classe caricati rimangono in memoria per sempre. Ogni nuova distribuzione carica un nuovo set di file di classe, il che significa che alla fine si esaurirà lo spazio PermGen.

+0

Come indicato da @Soundlink, i parametri per attivare GC in PermGen sono "-XX: + CMSClassUnloadingEnabled -XX: + CMSPermGenSweepingEnabled". Su Ubuntu dovresti aggiungerli a JAVA_OPTS in/etc/default/tomcat6. – werkshy

2

Gli switch PermGen in HotSpot ritardano il problema e alla fine si otterrà l'errore OutOfMemoryError.

Abbiamo avuto questo problema da molto tempo e l'unica soluzione che ho trovato finora è usare JRockit. Non ha un PermGen, quindi il problema scompare. Lo stiamo valutando sui nostri server di prova ora e non abbiamo avuto un problema con PermGen dopo lo switch. Ho anche provato a ridistribuire più di 20 volte sul mio computer locale con un'app che ha generato questo errore prima di ridistribuirlo e tutto ha funzionato magnificamente.

JRockit è pensato per essere integrato in OpenJDK, quindi forse questo problema andrà via anche per le azioni Java in futuro.

http://www.oracle.com/technetwork/middleware/jrockit/overview/index.html

Ed è gratuito, sotto la stessa licenza come HotSpot:

https://blogs.oracle.com/henrik/entry/jrockit_is_now_free_and

+0

Ho pensato che JRockit mantenga le definizioni di classe in heap. Il tuo heap non cresce dopo ogni ridistribuzione? Cosa mostra "Controllo missione JRockit" sulla dimensione dell'heap? –

+0

L'heap rimane della stessa dimensione dopo ogni ridistribuzione, per quanto posso vedere. Ho provato di nuovo con circa 10 redeploys adesso. –

1

Quale versione di Tomcat stai usando? Tomcat 7 e 6.0.30 hanno molte funzionalità per evitare queste perdite, o almeno per avvertirti della loro causa.

This presentation di Mark Thomas di SpringSource (e Tomcat di lunga data) su questo argomento è molto interessante.

+0

La domanda è stata posta nel 2010. Tomcat 7 era in programma quindi. La nostra soluzione era un'applicazione che spegne Tomcat, copia la vecchia WAR nella directory di backup, scarica la nuova WAR da Hudson, avvia Tomcat. Utilizziamo due tomcats e un modello di distribuzione blu-verde. –

1

Solo per riferimento, è disponibile una nuova versione dello strumento Plumbr, in grado di monitorare e rilevare anche le perdite di generazione permanente.

Problemi correlati