Al igual que con cualquier problema de administración de memoria, esta es una historia larga, por lo tanto, con correa.Confusing Tomcat Perfil de memoria de sesión persistente
Tenemos una aplicación que ha estado sufriendo algunos problemas de administración de memoria, así que he estado tratando de perfilar la aplicación para tener una idea de dónde radica el problema. Vi este hilo el día de hoy:
Tomcat Session Eviction to Avoid OutOfMemoryError
... que parece hacer lo mismo con lo que estaba viendo en el generador de perfiles. Básicamente, si presiono la aplicación con un grupo de usuarios con Jmeter, se mantendría en la memoria del montón durante mucho tiempo, hasta que las sesiones comenzaran a expirar. Sin embargo, a diferencia del póster en ese hilo, tengo la fuente y la opción de intentar implementar sesiones de estado persistentes con Tomcat, que es lo que he intentado hacer hoy, con un éxito limitado. Creo que es una configuración que me falta. Esto es lo que tengo en context.xml:
<Manager className='org.apache.catalina.session.PersistentManager'
saveOnRestart='false'
maxActiveSessions='5'
minIdelSwap='0'
maxIdleSwap='1'
maxInactiveInterval='600'
maxIdleBackup='0'>
<Store className='org.apache.catalina.session.FileStore'/>
</Manager>
Y en web.xml tengo esto:
<session-config>
<session-timeout>
10
</session-timeout>
</session-config>
Tu lugar ideal para las sesiones de tiempo de espera de una hora, pero para propósitos de prueba esta está bien. Ahora, después de haber jugado un poco con algunas cosas y, finalmente, llegar a estos ajustes, estoy viendo la aplicación en el perfilador y esto es lo que estoy viendo:
Como se puede ver en la imagen, no tengo poner algunas anotaciones Es la parte rodeada alrededor del signo de interrogación que realmente no entiendo más que cualquier otra cosa. Puede ver que estoy usando el botón 'Realizar CG' de Jconsole en algunos puntos diferentes, y puede ver la parte en el gráfico donde estoy llegando a la aplicación con muchos clientes con Jmeter.
Si recuerdo correctamente (tendría que volver atrás y realmente documentarlo para estar seguro), antes de implementar el estado persistente, el botón GC no haría tanto como para borrar el montón. Lo extraño aquí es que parece que tengo que ejecutar manualmente GC para este estado persistente para realmente ayudar con cualquier cosa.
Como alternativa, ¿se trata simplemente de un escenario de pérdida de memoria normal? Hoy temprano, tomé un volcado de pila y lo cargué en la herramienta Eclipse Memory Analyzer, y usé la función 'Detectar fuga', y todo lo que hice fue reforzar la teoría de que este es un problema de tamaño de sesión; la única filtración que detectó fue java.util.concurrent.ConcurrentHashMap $ Segment que me llevó a este hilo Memory Fully utilized by Java ConcurrentHashMap (under Tomcat)
lo que me hace pensar que no es la aplicación la que realmente está goteando.
Otros detalles relevantes: - Ejecutar/probar esto en mi máquina local por el momento. De ahí provienen todos estos resultados. - El uso de Tomcat 6 - Esta es una aplicación JSF2.0 - He añadido la propiedad del sistema -Dorg.apache.catalina.STRICT_SERVLET_COMPLIANCE = true según la documentación de Tomcat
lo tanto, creo que hay varias preguntas aquí : 1. ¿Tengo esto configurado correctamente? 2. ¿Hay una pérdida de memoria? 3. ¿Qué está pasando en este perfil de memoria? 4. ¿Es (relativamente) normal?
Gracias de antemano.
ACTUALIZACIÓN
tanto, he intentado consejos de Sean, y encontré algunas nuevas cosas interesantes.
El oyente de sesión funciona muy bien y ha sido fundamental para analizar este escenario. Otra cosa, que olvidé mencionar es que la carga de la aplicación solo se ve realmente confundida por una sola página, que alcanza una complejidad funcional en una proporción casi cómica. Entonces, en las pruebas, a veces intento golpear esa página, y otras veces la evito. Así que en mi próxima ronda de pruebas, esta vez usando el oyente de la sesión encontré lo siguiente:
1) Golpeé la aplicación con varias docenas de clientes, simplemente visitando una página simple. Noté que todas las sesiones se lanzaron como se esperaba después del límite de tiempo especificado, y se lanzó la memoria. Lo mismo funciona perfectamente con un número trivial de clientes, para el caso complejo, accediendo a la página 'grande'.
2) A continuación, traté de golpear la aplicación con el caso de uso complejo, con varias docenas de clientes. Esta vez, se iniciaron varias docenas de sesiones más de lo esperado. Parecía que cada cliente iniciaba entre una y tres sesiones. Después del tiempo de caducidad de la sesión, se liberó un poco de memoria, pero según el oyente de la sesión, solo se destruyó alrededor de un tercio de las sesiones. Contradiciendo que, sin embargo, la carpeta que en realidad contiene los datos de las sesiones está vacía. La mayor parte de la memoria que se usó se retendrá también. Pero, después de exactamente una hora de ejecutar la prueba de estrés, el recolector de basura se ejecuta y todo vuelve a la normalidad.
Por lo tanto, las preguntas de seguimiento incluyen:
1) ¿Por qué podrían las sesiones manejarse adecuadamente en el caso sencillo, pero cuando las cosas se ponen mucha memoria, dejan de ser administrado correctamente? ¿El controlador de sesión está informando incorrectamente sobre algo, o usar JMeter impacta de alguna manera?
2) ¿Por qué el recolector de basura espera una hora para correr? ¿Hay alguna configuración de sistema que obligue a que el recolector de basura DEBE ejecutarse dentro de un marco de tiempo dado, o si me falta alguna configuración de configuración?
Gracias de nuevo por la asistencia continua.
ACTUALIZACIÓN 2
Sólo una nota rápida: jugar con esta un poco más, descubrí la razón por la que estaba recibiendo diferentes informes sobre el número de sesiones en vivo es debido al hecho de que estoy usando persistente sesión; si lo desactivo, todo funciona como se espera. De hecho, dice en la página de Tomcat para sesión persistente, que es una característica experimental. Debe estar llamando a eventos de sesiones que el oyente está retomando, cuando uno esperaría atípicamente que lo hiciera.
Sean, gracias por la explicación en profundidad. Lamento no haber contactado antes. Básicamente publiqué y me desconecté durante el fin de semana. De todos modos, acepté su respuesta, pero también publiqué algunas preguntas de seguimiento, si tiene tiempo para ayudar más. Si no, sus consejos ya me han ayudado a seguir adelante, y su conclusión de que no hay pérdida de memoria me ha dado tranquilidad. – user470714