1. JMX (Java Management Extensions): el corazón de la monitorización de la JVM
La monitorización es como un chequeo médico periódico para su aplicación. Si el registro puede compararse con un diario donde se anota todo lo que ya ha ocurrido, la monitorización es un conjunto de instrumentos que muestran el estado del sistema ahora mismo: temperatura, pulso, presión, nivel de azúcar y otros indicadores vitales de la JVM.
Ayuda a entender cuánta memoria se usa realmente y si hay fugas, cuántos hilos están funcionando y en qué estado se encuentran —esperando, ejecutándose o bloqueados. Puede ver con qué frecuencia se activa el recolector de basura, cuán cargada está la CPU y detectar a tiempo síntomas preocupantes como un crecimiento repentino de la memoria o del número de hilos.
En resumen, el registro cuenta lo que ya pasó, y la monitorización muestra lo que está ocurriendo ahora mismo.
Fundamentos de JMX: qué es y para qué sirve
JMX es una tecnología de Java que permite observar la vida de su aplicación desde dentro e incluso controlarla un poco. Funciona mediante objetos especiales, los MBean (Management Bean). Se podría decir que son como «sensores» y «interruptores» dentro de la JVM: unos muestran el estado del sistema y otros permiten ajustar cosas.
Con JMX puede saber cuánta memoria tiene asignada ahora la JVM, cuántos hilos están activos, cuánto tiempo se dedica a la recolección de basura y mucho más, sin necesidad de tocar el código ni reiniciar la aplicación.
Cómo está construido
En la JVM, de serie ya hay numerosos MBean que proporcionan información sobre:
- memoria (heap, non-heap);
- recolectores de basura (GC);
- hilos;
- clases (cuántas se han cargado, descargado);
- e incluso sobre la propia JVM (versión, parámetros de inicio).
JMX es como el cuadro de instrumentos de un coche. Ve la velocidad, las revoluciones, la temperatura del motor, y todo eso está disponible a través de sensores estándar (MBean).
Cómo acceder a JMX
La forma más sencilla es usar la utilidad estándar JConsole, que viene con el JDK.
Inicio de JConsole
- Abra la terminal/la línea de comandos.
- Ejecute el comando:
jconsole - Seleccione el proceso de Java que quiera monitorizar (por ejemplo, su aplicación).
JConsole se conectará a la JVM mediante JMX y mostrará gráficas y tablas: uso de memoria, número de hilos, actividad del recolector de basura, etc.
Ejemplo: ver la memoria y los hilos
En JConsole abra las pestañas "Memory" y "Threads". Verá cómo varía el volumen de memoria usada, cuántos hilos están vivos ahora, cuáles están activos y cuáles esperando.
MBean personalizados
Puede crear sus propios MBean para monitorizar métricas propias (por ejemplo, el número de pedidos procesados). Pero eso ya es para niveles avanzados: los MBean estándar proporcionan muchísima información.
2. VisualVM — monitorización visual y perfilado
Si JConsole es el «cuadro de instrumentos», VisualVM es todo un centro de diagnóstico con rayos X, RM y análisis de sangre. Permite no solo monitorizar, sino también perfilar la aplicación, obtener heap dump, analizar fugas y ver qué métodos consumen más tiempo.
Instalación e inicio de VisualVM
- VisualVM se incluye con el JDK (normalmente como jvisualvm), pero puede descargar la versión más reciente en visualvm.github.io.
- Se inicia con el comando:
jvisualvm - Tras iniciarse, verá la lista de todos los procesos de Java que se están ejecutando en su máquina.
Conexión a un proceso
- Busque su proceso (por ejemplo, Main o MyApp) en la lista.
- Haga doble clic en él; se abrirá una pestaña con información sobre el proceso.
- ¡Listo! Ahora verá:
- Uso de CPU y memoria en tiempo real.
- Cantidad de hilos y su estado.
- Lista de clases cargadas.
- La posibilidad de obtener heap dump y thread dump.
Funciones principales de VisualVM
Con VisualVM puede observar cómo se usa la memoria —tanto el heap como el non-heap—. En la gráfica verá si el consumo crece o se estabiliza. Para comprobar el funcionamiento del recolector de basura, pulse el botón "Perform GC" — la JVM intentará limpiar la memoria de inmediato. Puede hacer un heap dump (captura de memoria) y estudiarlo para buscar fugas.
La herramienta también muestra el estado de los hilos: cuántos están iniciados, cuáles trabajan, esperan o están bloqueados. Si se produce un deadlock, VisualVM ayudará a detectarlo y mostrar los bloqueos mutuos.
Para un análisis en profundidad hay perfilado: verá los «puntos calientes» de métodos que consumen más tiempo de CPU o memoria. Es útil para diagnosticar caídas inesperadas de rendimiento.
Ejemplo: monitorizamos una miniaplicación
public class MemoryLeakDemo {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memoryConsumers = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
memoryConsumers.add(new byte[1024 * 1024]); // 1 MB
Thread.sleep(100); // Esperamos un poco para que la gráfica sea más suave
}
System.out.println("¡Listo! No olvide mirar en VisualVM :)");
Thread.sleep(60000); // Mantenemos la aplicación abierta para el análisis
}
}
Ahora:
- Ejecute el programa.
- Abra VisualVM y conéctese al proceso.
- Observe cómo crece el uso de memoria.
- Obtenga un heap dump y encuentre los arrays que ocupan memoria.
3. Java Flight Recorder (JFR): la «caja negra» para la JVM
Qué es JFR
Java Flight Recorder es una herramienta integrada en la JVM para recopilar eventos detallados sobre el funcionamiento de la aplicación. Es una «caja negra»: JFR registra lo que ocurre en la JVM para encontrar después cuellos de botella o causas de incidentes.
JFR recopila:
- eventos de GC;
- información sobre hilos;
- frecuencia de llamadas de métodos y perfiles de tiempo;
- pausas y latencias;
- excepciones y errores.
Cómo activar JFR
Desde Java 11+, JFR está incluido directamente en OpenJDK.
Inicio con JFR
java -XX:StartFlightRecording=filename=recording.jfr,duration=60s,settings=profile -jar MyApp.jar
- filename=recording.jfr — dónde guardar la grabación.
- duration=60s — cuánto tiempo grabar.
- settings=profile — nivel de detalle (default, profile, continuous).
Visualización de resultados
Para analizar el archivo .jfr se utiliza JDK Mission Control (JMC):
- Descargar JMC: jdk.java.net/jmc
- Abrir el archivo recording.jfr.
- Estudiar las gráficas, los «puntos calientes» de métodos, las pausas de GC y la actividad de los hilos.
Ejemplo: grabamos la «caja negra»
- Inicie la aplicación con JFR (véase el comando anterior).
- Abra JDK Mission Control y cargue el archivo de la grabación.
- Evalue los «puntos calientes» por CPU/memoria, la frecuencia de las recolecciones de basura y el número de hilos activos.
4. Práctica: monitorizamos una aplicación
import java.util.ArrayList;
import java.util.List;
public class MonitoringExample {
public static void main(String[] args) throws InterruptedException {
List<byte[]> memory = new ArrayList<>();
for (int i = 0; i < 50; i++) {
memory.add(new byte[2 * 1024 * 1024]); // 2 MB
Thread.sleep(500);
}
// Iniciamos un hilo
new Thread(() -> {
while (true) {
try {
Thread.sleep(1000);
System.out.println("El hilo en segundo plano está funcionando...");
} catch (InterruptedException e) {
break;
}
}
}).start();
Thread.sleep(20000); // Mantenemos la aplicación abierta para la monitorización
}
}
Acciones:
- Ejecute el programa.
- Abra VisualVM, busque el proceso y observe la gráfica de memoria y los hilos.
- Intente obtener un heap dump y un thread dump.
- Para avanzados: inicie con JFR y vea los resultados en JMC.
5. Matices útiles
Tabla comparativa de herramientas de monitorización
| Herramienta | Para qué sirve | Cómo iniciarlo | Características |
|---|---|---|---|
| JConsole (JMX) | Métricas básicas de la JVM, hilos, GC | |
Sencillo, incluido en el JDK |
| VisualVM | Monitorización, perfilado, heap dump | |
Gráficas, análisis de memoria, CPU |
| Java Flight Recorder | Análisis profundo de eventos de la JVM | |
Análisis en JMC, «caja negra» |
| JDK Mission Control | Visualización de archivos JFR | programa independiente | Analítica detallada, informes |
Recomendaciones
- Monitorice no solo en producción, sino también en la fase de pruebas. Así detectará antes fugas de memoria e hilos «colgados».
- ¡El heap dump no duele! Obtenga un volcado de memoria si sospecha de una fuga y estúdielo en VisualVM.
- No tema experimentar con JFR. Aunque no todo se entienda a la primera, los eventos y las gráficas ayudarán a encontrar cuellos de botella.
- JMX puede usarse por programación. Por ejemplo, para enviar métricas a Prometheus/Grafana.
- El perfilado no es para uso continuo. Active los perfiladores de forma puntual; de lo contrario, la aplicación puede ralentizarse.
6. Errores típicos al monitorizar la JVM
Error n.º 1: no monitorizar en absoluto. Muchos principiantes piensan que si la aplicación «funciona», todo está bien. En realidad, los problemas de memoria y hilos a menudo se manifiestan bajo carga o con el tiempo. No sea perezoso y abra VisualVM/JConsole al menos periódicamente.
Error n.º 2: obtener un heap dump en aplicaciones enormes sin preparación. Un heap dump de una aplicación grande puede pesar gigabytes y «congelar» el proceso durante varios segundos. Hágalo en un entorno de pruebas o en horas «valle» si se trata de producción.
Error n.º 3: ignorar los indicadores de GC y de hilos. ¡Una proporción de tiempo constantemente alta en GC es una señal de alarma! Y si el número de hilos crece de forma estable, busque una fuga de hilos.
Error n.º 4: no analizar los resultados de la monitorización. Solo abrir VisualVM no basta. Vea qué objetos ocupan memoria, qué métodos «se comen» la CPU, por qué aparecen deadlocks. Analice los stack traces y las causas.
Error n.º 5: usar perfiladores en producción sin comprenderlos. El perfilado puede ralentizar significativamente la aplicación. Actívelo solo para diagnóstico, no «de forma permanente».
GO TO FULL VERSION