Estamos ejecutando una pequeña aplicación web escrita JRuby on Rails que se ejecuta bajo Tomcat. Estamos usando un back-end de Spring que se comparte con otra aplicación web de producción. Desafortunadamente, seguimos encontrando problemas con PermGen.Localiza el problema de PermGen con JRuby on Rails en Tomcat
OS: Ubuntu Linux 2.6.24-24-servidor # 1 SMP x86_64 GNU/Linux Java: 1.6.0_21 Tomcat: 6.0.28 JRuby: 1.5.0 Rieles: 2.3.7
Actualmente estamos siendo rastreados por Google, Yahoo y Baidu, por lo que el uso del sitio está activo. He estado monitorizando Tomcat con JConsole y definitivamente estamos viendo un problema con un número excesivo de clases. Cuando se lanza Tomcat, tenemos aproximadamente 12,000 clases cargadas. Después de 8 horas, tenemos casi 75,000 clases cargadas. PermGen va de 100MB a 460MB en el mismo tiempo.
La descarga de clases está funcionando, pero solo descargó ~ 500 clases en ese mismo período de 8 horas. PermGen nunca parece ser recolectado.
nos estamos quedando con las siguientes opciones de VM para Tomcat:
-Xms2048m -Xmx2048m -XX:MaxPermSize=512m -XX:PermSize=128m \
-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=4 \
-XX:+CMSClassUnloadingEnabled -XX:+CMSPermGenSweepingEnabled
Obviamente hay algún tipo de fuga. La pregunta es ¿dónde? ¿Algún consejo sobre cómo rastrear quién y qué es responsable de esto? Espero que sea un error muy tonto de nuestra parte, pero no estoy seguro de por dónde empezar.
Cualquier consejo sería muy apreciado.
EDITAR
Parece que estamos viendo una nueva clase creada para cada solicitud entrante sola.
EDITAR 2
Es definitivamente relacionadas con JRuby. Utilizando JConsole, habilité el modo Verbose para el cargador de clases. He aquí una muestra de 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]
Entonces la pregunta es ¿cómo puedo localizar a la parte responsable de la creación de esas clases adicionales?
EDITAR 3
No estoy seguro si este problema, pero de alguna manera estamos terminando con un número increíble de cargadores de clases. Ran jmap -permstat PID
y obtuvo:
class_loader classes bytes parent_loader alive? type
total = 1320 135748 947431296 N/A alive=1, dead=1319 N/A
Eso parece un poco excesivo. La mayoría son uno de los tres tipos de cargadores de clase: sun.reflect.DelegatingClassLoader
, org.jruby.util.JRubyClassLoader
o org.jruby.util.ClassCache$OneShotClassLoader
. Una vez más, muestra de salida de 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 clases para 4 instancias todavía me parece mucho ... :) Pero definitivamente haré algunas pruebas más. ¡Gracias! – organicveggie
Lo que me preocupa es que parece que cada nueva solicitud crea nuevas clases que nunca se publican. Eso simplemente no me parece bien. Entiendo por qué JRuby está creando nuevas clases, pero no puedo entender por qué no se limpian ... – organicveggie
¿Cómo puedo saber si jruby.compile.mode = OFF funciona correctamente? Agregué -Djruby.compile.mode = OFF a CATALINA_OPTS en catalina.sh, inicié tomcat y lancé un webcrawler contra el sitio. JConsole indica que el recuento total de clases y el permgen total aumenta constantemente. – organicveggie