Compilador JIT de Java que causa OutOfMemoryError

Una aplicación que recientemente comenzamos a fallar esporádicamente con un mensaje sobre "java.lang.OutOfMemoryError: solicitó 8589934608 bytes para Chunk :: new. ¿Fuera del espacio de intercambio?".

He mirado alrededor en la red, y en todas partes las sugerencias se limitan a

volver a una versión anterior de Javajugar con la configuración de memoriausar cliente en lugar de modo servidor

Volver a una versión anterior implica que el nuevo Java tiene un error, pero no he visto ninguna indicación de eso. La memoria no es un problema en absoluto; el servidor tiene 32 GB disponibles, y Xmx está configurado en 20, mientras que Xms es 10. No puedo ver que la JVM se quede sin los 12 GB restantes (menos la cantidad dada a los otros procesos en la máquina). Y estamos atascados con el modo de servidor debido a la naturaleza de la aplicación y el entorno.

Cuando miro el uso de la memoria y la CPU para la aplicación, veo un uso constante de la memoria durante todo el día, pero de repente justo antes de que muera, el uso de la CPU aumenta al 100% y el uso de la memoria va de X a X + 2GB, a X + 4GB, a (a veces) X + 8GB, a la muerte de JVM. Parece que hay un ciclo de redimensionamiento de matriz repetido en la compilación JIT.

Ahora he visto que se produce el error con la solicitud anterior de 8 GB y también con las solicitudes de 16 GB. En todo momento, el método que se compila cuando esto sucede es el mismo. Es un método simple que tiene bucles no anidados, sin recursión, y utiliza métodos en objetos que devuelven campos de miembros estáticos o campos de miembros de instancia directamente con poco cálculo.

Entonces tengo 2 preguntas:

¿Alguien tiene alguna sugerencia?¿Puedo probar si hay un problema al compilar este método específico en un entorno de prueba, sin ejecutar toda la aplicación, invocando el compilador JIT directamente? ¿O debería iniciar la aplicación y decirle que compile métodos después de un recuento de llamadas mucho menor (como 2) para forzarlo a compilar el método casi instantáneamente en lugar de hacerlo en un punto aleatorio del día?

@StephenC

La JVM es 1.6.0_20 (anteriormente 1.6.0_0), que se ejecuta en Solaris. Sé que es la compilación la que está causando un problema por un par de razones.

ps en los segundos anteriores muestra que un subproceso java con id correspondiente al subproceso del compilador (desde jstack) ocupa el 100% del tiempo de CPUjstack muestra que el problema está enJavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]

El método mencionado enjstack es siempre el mismo, y es uno que escribimos. Si nos fijamos en la muestrajstack de salida sabrá a qué me refiero, pero por razones obvias no puedo proporcionar ejemplos de código o nombres de archivo. Diré que es un método muy simple. Essentiall un puñado de comprobaciones nulas, 2 para bucles que realizan comprobaciones de igualdad y posiblemente asignan valores, y algunas llamadas a métodos simples después. En total, tal vez 40 líneas de código.

Este problema ha sucedido 2 veces en 2 semanas, aunque la aplicación se ejecuta todos los días y se reinicia a diario. Además, la aplicación no estaba bajo carga pesada ninguno de estos tiempos.

Respuestas a la pregunta(3)

Su respuesta a la pregunta