Domanda

Sto eseguendo Tomcat6 in Sun JRE6 e ogni coppia distribuisce ottengo OutOfMemoryException: PermGen. Ho fatto il googling delle soluzioni PermGen e ho provato molte correzioni. Nessuno funziona. Ho letto un sacco di cose positive su JRockit di Oracle e su come la sua allocazione PermGen può essere di dimensioni gigantesche (rispetto ai 128M di Sun) e mentre non risolve il problema, mi consentirebbe di ridistribuire 100 volte tra le eccezioni PermGen rispetto a 2 volte adesso.

Il problema con JRockit è di usarlo in produzione, è necessario acquistare WebLogic che costa migliaia di dollari. Quali altre opzioni (gratuite) esistono che perdonano maggiormente l'espansione di PermGen? Come funzionano le JVM sottostanti in quest'area?

  • IBM JVM
  • Apri JDK
  • Blackdown
  • Kaffe

... altri?

Aggiornamento: alcune persone hanno chiesto perché pensassi che PermGen max fosse 128M. Il motivo è perché ogni volta che provo a portarlo sopra 128M la mia JVM non riesce a inizializzare:

[2009-06-18 01:39:44] [info] Si è verificato un errore durante l'inizializzazione della VM [2009-06-18 01:39:44] [info] Impossibile riservare spazio sufficiente per l'heap di oggetti [2009-06-18 01:39:44] [395 javajni.c] [errore] CreateJavaVM non riuscito

È strano che non riesca a riservare spazio per l'oggetto heap , anche se non sono sicuro che sia " il " heap anziché " a " mucchio.

Avvio JVM con 1024 MB iniziali e heap massimo 1536 MB.

Chiuderò questa domanda poiché ha ricevuto risposta, vale a dire. "La commutazione è inutile" e chiedi invece Perché il mio Sun JVM fallisce con impostazioni PermGen più grandi?

È stato utile?

Soluzione

Sono d'accordo con Michael Borgwardt sul fatto che è possibile aumentare le dimensioni di PermGen, non sono d'accordo sul fatto che è principalmente dovuto a perdite di memoria. Lo spazio PermGen viene consumato in modo aggressivo da applicazioni che implementano un uso intenso di Reflection. Quindi, fondamentalmente, se hai un'applicazione Spring / Hibernate in esecuzione su Tomcat, preparati a incrementare molto lo spazio di PermGen.

Altri suggerimenti

Cosa ti ha dato l'idea che la JVM di Sun sia limitata a 128M PermGen? Puoi impostarlo liberamente con l'opzione -XX: MaxPermSize della riga di comando; il valore predefinito è 64M.

Tuttavia, la vera causa del tuo problema è probabilmente una perdita di memoria nella tua applicazione che impedisce alle classi di essere spazzate via; questi possono essere molto sottili, specialmente quando sono coinvolti ClassLoaders, poiché tutto ciò che serve è un singolo riferimento a qualsiasi classe, ovunque. Questo articolo descrive il problema in dettaglio e questo suggerisce modi per risolverlo.

Tecnicamente, il "PermGen" il pool di memoria è una cosa di Sun JVM. Altri JVM non lo chiamano così, ma tutti hanno l'idea di uno o più pool di memoria non heap.

Ma se hai un problema con permgen nella tua JVM Sun, è molto improbabile che spostarsi su un'altra JVM risolva qualcosa, si manifesterà semplicemente con un nome diverso.

Se più ridistribuzioni causano problemi, è sufficiente aumentare PermGen della VM fino a valori elevati. Abbiamo provato JRockit qualche tempo fa proprio per questo problema, e soffre della stessa stanchezza da riassegnazione. Siamo tornati a SUn JVM.

La modifica di JVM non è una panacea. È possibile riscontrare nuovi problemi imprevisti (ad esempio consultare un articolo sull'avvio di un'applicazione con 4 diverse JVM).

  • È possibile che si verifichi una perdita di classe (ad es. tramite classloader) che spesso si verifica durante la ridistribuzione. Francamente, non ho mai visto lavorare a ridistribuzione a caldo su Tomcat (spero di vedere un giorno).
  • È possibile avere parametri JVM errati (ad es. per Sun JDK 6 64 bit -XX: + Lo switch UseParNewGC porta alla perdita del segmento di memoria PermGen. Se si aggiungono switch aggiuntivi: -XX: + UseConcMarkSweepGC -XX: + CMSClassUnloadingEnabled-XX: + CMSPermGenSweepingEnabled la situazione verrà risolta: divertente, ma non ho mai incontrato la perdita sopra menzionata con Sun JDK 6 32 bit). Link a un articolo " Ottimizzazione di JVM Garbage Collection per distribuzioni di produzione " .
  • Il tuo pezzo PermGen può non essere sufficiente per caricare classi e informazioni correlate (in realtà ciò accade più spesso dopo la ridistribuzione sotto Tomcat, le vecchie classi rimangono in memoria e quelle nuove vengono caricate)

Dalla mia esperienza passata, il debug di quel tipo di perdita è uno dei tipi più difficili di debug che io abbia mai avuto.

[AGGIORNATO]

Articolo utile come eliminare il collegamento del classloader su una ridistribuzione dell'applicazione.

Uso JRockit e ricevo ancora errori PermGen se non eseguo il backup (tramite -XX: MaxPermSize) della memoria. Inoltre non riesco a far funzionare nulla per evitarlo (tranne aumentarlo).

Perm gen è probabilmente la memoria più semplice da gestire, dubito che ci sarebbe molta differenza tra le varie implementazioni VM.

Assicurati che tutte quelle configurazioni Tomcat contrassegnate come disattivate in produzione siano disattivate in produzione.

Sì, alcuni framework che generano molte classi al volo, ma dovrebbero ripulire dopo se stessi e, in ogni caso, è possibile inserire più di alcune classi in 128 Mb.

Seriamente, se perm gen continua a salire, allora questa dovrebbe essere riparata, anche se potrebbe non essere il tuo problema da risolvere.

La IBM JVM non funziona (e non è stata 2009) hanno un permgen. Puoi leggere ulteriori informazioni su Generational Concurrent Garbage Collector che è il GC predefinito per Java 7.

A volte ho eseguito l'IDE Eclipse su IBM JVM in particolare perché con i miei plugin preferiti riempirebbe spesso il permesso di HotSpot JVM. Certo, probabilmente c'era una perdita di memoria che qualcuno avrebbe dovuto risolvere, ma nel frattempo il mio IDE non si stava arrestando in modo anomalo e non ero impegnato a sperimentare impostazioni diverse.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top