Stiamo eseguendo una piccola applicazione Web scritta JRuby su Rails in esecuzione su Tomcat. Stiamo utilizzando un back-end di Spring condiviso con un'altra applicazione web di produzione. Sfortunatamente, continuiamo a imbattersi in problemi PermGen.Rintracciare il problema PermGen con JRuby su Rails in Tomcat
OS: Ubuntu Linux 2.6.24-24-server di # 1 SMP x86_64 GNU/Linux Java: 1.6.0_21 Tomcat: 6.0.28 JRuby: 1.5.0 Rails: 2.3.7
Al momento siamo sottoposti a scansione da Google, Yahoo e Baidu, pertanto l'utilizzo del sito è scaduto. Ho monitorato Tomcat con JConsole e stiamo sicuramente riscontrando un problema con un numero eccessivo di classi. All'avvio di Tomcat, abbiamo circa 12.000 classi caricate. Dopo 8 ore, abbiamo caricato quasi 75.000 classi. PermGen va da 100 MB a 460 MB nello stesso tempo.
Lo scaricamento della classe sta funzionando, ma ha scaricato solo ~ 500 classi nello stesso periodo di 8 ore. PermGen non sembra mai essere raccolto.
stiamo correndo con le seguenti opzioni VM per Tomcat:
-Xms2048m -Xmx2048m -XX:MaxPermSize=512m -XX:PermSize=128m \
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 \
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
Ovviamente c'è un qualche tipo di perdita. La domanda è come dove? Qualche consiglio su come rintracciare chi e cosa è responsabile di questo? Spero che sia un errore davvero stupido da parte nostra, ma non sono sicuro da dove cominciare.
Qualsiasi consiglio sarebbe molto apprezzato.
EDIT
Sembra che stiamo vedendo una nuova classe creata per ogni singola richiesta in arrivo.
EDIT 2
è sicuramente legato alla JRuby. Usando JConsole, ho abilitato la modalità Verbose per il caricatore di classi. Ecco un esempio da catalina.out:
[Loaded anon_class1275113147_895127379 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
[Loaded anon_class1354333392_895127376 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
[Loaded anon_class1402528430_895127373 from file:/opt/apache-tomcat-6.0.28/webapps/notes/WEB-INF/lib/jruby-core-1.5.0.jar]
Quindi la domanda diventa come faccio a rintracciare il responsabile per la creazione di quelle classi in più?
EDIT 3
Non sono sicuro se questo il problema, ma in qualche modo ci stiamo finendo con un numero folle di caricatori di classe. Ran jmap -permstat PID
e ottenuto:
class_loader classes bytes parent_loader alive? type
total = 1320 135748 947431296 N/A alive=1, dead=1319 N/A
Sembra un po 'eccessivo. La maggior parte sono uno dei tre tipi di classloader: sun.reflect.DelegatingClassLoader
, org.jruby.util.JRubyClassLoader
o org.jruby.util.ClassCache$OneShotClassLoader
. Anche in questo caso, il campione di uscita dal jmap -permstat
:
class_loader classes bytes parent_loader alive? type
0x00007f71f4e93d58 1 3128 0x00007f71f4d54680 dead sun/reflect/[email protected]
0x00007f721e51e2a0 57103 316038936 0x00007f720431c958 dead org/jruby/util/[email protected]
0x00007f72182f2b10 4 12944 0x00007f721d7f3030 dead org/jruby/util/[email protected]
0x00007f721d7d50d8 9 457520 0x00007f720431c958 dead org/jruby/util/[email protected]
75.000 classi per 4 istanze mi sembrano ancora molto ... :) Ma farò sicuramente qualche altro test. Grazie! – organicveggie
La cosa che mi riguarda è che sembra che ogni nuova richiesta crei nuove classi che non vengono mai rilasciate. Questo non mi sembra giusto. Capisco perché JRuby sta creando nuove classi, ma non riesco a capire perché non vengono ripulite ... – organicveggie
Come posso sapere se jruby.compile.mode = OFF funziona correttamente? Ho aggiunto -Djruby.compile.mode = OFF a CATALINA_OPTS in catalina.sh, ho avviato tomcat e lanciato un webcrawler contro il sito. JConsole indica che il conteggio totale della classe e il permgen totale sono in costante aumento. – organicveggie