/
Usando JStack y JMap para analizar los módulos de Onesait Platform

Usando JStack y JMap para analizar los módulos de Onesait Platform

Disponible desde la versión 6.3.0-Yoshi

Introducción

Se ha incorporado a la imagen base de los contenedores de Onesait Platform un par de utilidades nuevas de la JDK: JStack y JMap, las cuales por defecto no se incorporan en las imágenes base de OpenJDK.

Ambas herramientas son de utilidad cuando determinados módulos empiezan a funcionar de manera anómala, ya sea por un uso no adecuado o que requiera de un ajuste fino de parámetros, de acuerdo al proyecto donde se esté utilizando.

Entre algunas de las anomalías que estas herramientas considera se encuentran:

  • Errores de tipo Out-Of-Memory.

  • Módulos incapaces de responder a nuevas peticiones.

  • Errores de agotamiento de pool de conexiones.

  • Errores de agotamiento de pools workers.

  • Degradación de rendimiento.

¿Qué es JStack?

JStack es una herramienta diseñada para generar un volcado de pila (thread dump) de una máquina virtual Java (JVM) en ejecución. Este volcado muestra información detallada sobre los hilos que están siendo ejecutados, entre los que se incluyen:

  • Estados de los hilos: como por ejemplo, si están en ejecución, bloqueados o en espera.

  • Trazas de pila: líneas de código donde se encuentra cada hilo.

  • Bloqueos de recursos: hilos que están esperando el acceso a recursos compartidos.

https://www.ibm.com/docs/en/semeru-runtime-ce-z/21?topic=tools-java-stack-jstack-tool

Casos de uso principales

En general, JStack es utilizado en:

  1. Diagnóstico de bloqueos (deadlocks): pues identifica los hilos que están esperando indefinidamente por recursos.

  2. Análisis de rendimiento: ya que detecta cuellos de botella observando qué hilos consumen más recursos.

  3. Resolución de errores: obtiene contexto cuando una aplicación no responde o muestra un comportamiento inusual.

¿Cómo se usa JStack?

Para utilizar JStack, simplemente se tiene que ejecutar el siguiente comando desde la línea de comandos:

jstack <pid>

Donde pid es el identificador del proceso de la JVM en ejecución. Se puede encontrar el PID usando herramientas tales como jps (Java Process Status) o ps en sistemas Unix.

 

¿Qué es JMap?

JMap es otra herramienta que se utiliza para inspeccionar el uso de memoria de una aplicación Java. Ofrece información detallada sobre el heap de la JVM, como:

  • Estructura del heap: con la distribución de objetos en memoria.

  • Estadísticas de uso: con la cantidad de memoria usada y disponible.

  • Histogramas de objetos: con información sobre el tipo y la cantidad de objetos en el heap.

Casos de uso principales de JMap

El uso de JMap es útil para:

  1. Detección de fugas de memoria (memory leaks): analizando el volcado del heap se va a poder identificar objetos que no se liberan correctamente.

  2. Optimización del uso de memoria: permite comprender qué partes de la aplicación consumen más recursos.

  3. Análisis del comportamiento del garbage collector: que permite evaluar cómo los objetos se acumulan y eliminan en la aplicación.

¿Cómo se usa JMap?

JMap tiene varias opciones útiles, entre las que se incluyen:

  • Obtener un histograma de objetos:

jmap -histo <pid>

Generar un volcado del heap:

jmap -dump:format=b,file=heap_dump.hprof <pid>

Este archivo puede ser analizado posteriormente con herramientas como Eclipse MAT (Memory Analyzer Tool).

Cómo utilizar JStack y JMap con los módulos de Onesait Platform

Ambas herramientas se utilizan de una manera similar. A continuación se va a ilustrar el proceso utilizando ambas en un entorno OpenShift con Onesait Platform desplegada.

En primer lugar se procederá a conectarse a través de OpenShift a la terminal del Pod al que le se quiere hacer un volcado de hilos o de memoria.

image-20241217-102845.png

A continuación, se identificará el PID del proceso utilizando el siguiente comando:

image-20241217-102917.png

Tras la ejecución, se identificará que el PID del proceso es el 1. Conociendo esto, se estará en disposición de hacer un volcado de hilos y/o de memoria. Esto se llevará a cabo con los siguientes comandos:

Esto generará el volcado de hilos en el archivo /tmp/volcadohilos.txt

Esto dará lugar al volcado de memoria en el archivo /tmp/volcadomemoria.hprof

Una vez que se ha generado estos archivos, hay que descargarlos desde el contenedor hasta la máquina local, donde se procederá a su análisis. Para ello, s de hace uso de estas dos utilidades:

  • oc: CLI (Command Line Interface) de Openshift.

  • kubectl: CLI genérico para Kubernetes.

 Con oc se hará que la máquina quede autenticada en el clúster de OpenShift (Kubernetes) y pueda acceder al Pod donde se ha generado los volcados de hilos y memoria para descargarlos.

Para ello, en la consola web de Openshift se desplegarán las opciones del usuario usuario:

De las diferentes opciones que aparecen, se seleccionará la de «Copy login command». Esto hará que se tenga que volver a autenticar en la consola web, y se redirigirá a una pantalla en blanco donde sólo s la e tendrá la opción de «Display Token».

Pulsando sobre el enlace, se mostrará el comando oc login a ejecutar:

Se copia todo el comando oc login y se tendrá que ejecutar en una terminal del ordenador:

A continuación, se seleccionará el proyecto donde está el Pod al que se quiere acceder usando el siguiente comando:

Finalmente, se copiará los archivos a la máquina local con el siguiente comando:

En el caso de la Plataforma:

Análisis de volcado de hilos con JStack

Existen multitud de herramientas para analizar un volcado de hilos. Algunas de ellas son:

  • Eclipse o IntelliJ, a través de plugins.

  • VisualVM.

  • TDA de IBM.

  • FastThread.

En el caso de Onesait Platform, se va a utilizar FastThread, ya que se trata de un servicio web, que no necesita ser instalado en el ordenador y que permite subir el archivo generado con JStack para analizarlo de manera muy eficiente, incluso aplicando algoritmos para detectar problemas.

Una vez cargado en el servicio el volcado de hilos, se mostrará el siguiente panel de control, donde automáticamente se han agrupado los hilos según el Thread Pool al que pertenecen, y su estado. Esto va a permitir hacerse una idea rápida del estado del módulo cuando se extrajo el volcado de hilos:

 

Desde esta vista, conociendo que para este caso en particular el problema era de agotamiento del pool de conexiones a la base de datos, se podrá centrar la atención en dos puntos:

  • Hilos bloqueados:

  • Pools de hilos que están a su máximo de capacidad:

Se puede remitir al código fuente para identificar al lógica de negocio que está causando el problema, lo que ayuda a detectar que, en este caso en concreto, un número inadecuado de tareas asíncronas, que luego quedaban a espera de un cambio de estado, estaban reservando la conexión a base de datos durante toda la espera del cambio de evento.

Análisis de volcado de hilos con JMap

También existen multitud de herramientas para analizar un volcado de memoria, tales como:

  • Eclipse MAT.

  • VisualVM.

  • JProfiler.

Para el caso de la Plataforma, se va a hablar de Eclipse MAT, el cual es un entorno eclipse diseñado exclusivamente para analizar volcados de memoria.

Al cargar un volcado de memoria, se puede ver un pequeño panel de control mostrando la distribución de uso de la memoria, junto con los posibles problemas encontrados, derivados de objetos que consumen una cantidad porcentual de memoria bastante alta con relación al resto:

Localizar problema de memoria normalmente se fundamenta en navegar por el Dominator Tree de objetos, ordenado por Eclipse MAT según su tamaño:

También es posible examinar el histograma, que muestra un resumen de todos los objetos en el heap, organizados por su tipo y proporciona información clave sobre su distribución y uso.

Conclusión

Disponer de estas herramientas en la imagen base del contenedor de Onesait Platform va a permitir generar evidencias de problemas que podrán ser analizadas por el equipo de soporte, para determinar de acuerdo a cada proyecto la configuración necesaria según sus necesidades, así como la detección y corrección de bugs.