CodeGym /Cursos /JAVA 25 SELF /Herramientas de análisis de memoria: jmap, jvisualvm

Herramientas de análisis de memoria: jmap, jvisualvm

JAVA 25 SELF
Nivel 64, Lección 3
Disponible

1. jmap: magia en la línea de comandos

El recolector de basura automático es, por supuesto, estupendo. Pero incluso las aplicaciones Java pueden «tener fugas» (OutOfMemoryError), funcionar lentas o atascarse inesperadamente por un uso incorrecto de la memoria. Las causas pueden ser diversas:

  • Fugas de memoria (memory leaks): objetos que deberían haberse eliminado siguen «vivos».
  • Volúmenes de datos demasiado grandes en las colecciones.
  • Errores en la lógica de caché.
  • Recursos no liberados (por ejemplo, hilos, archivos).

Su objetivo es aprender a encontrar rápidamente este tipo de problemas. ¡De lo contrario, corre el riesgo de convertirse no en programador, sino en «desarrollador de bugs»!

¿Qué es jmap?

jmap es una utilidad incluida en el JDK estándar. Permite obtener un «volcado» (heap dump) de la memoria de un proceso Java en ejecución. Este volcado puede abrirse después en otras herramientas y ver qué objetos ocupan memoria, cuántos hay y quién los referencia.

Heap dump es como una fotografía de su heap: todos los objetos que hay en él, sus tipos, relaciones y tamaños.

Cómo usar jmap

Encuentre el PID del proceso

Para empezar, hay que averiguar el identificador del proceso (PID) en el que se ejecuta su aplicación Java. Esto se puede hacer de varias maneras:

Con jps (otra utilidad del JDK):

jps -l

Verá una lista de procesos Java y sus PID.

A través del Administrador de tareas (Task Manager) o ps en Linux.

Obtenga un volcado de memoria

jmap -dump:format=b,file=heap.bin <PID>
  • format=b — formato binario (adecuado para el análisis).
  • file=heap.bin — nombre del archivo donde se guardará el volcado.
  • <PID> — identificador del proceso.

Ejemplo:

jmap -dump:format=b,file=heap.bin 12345

¿Qué hacer con el heap dump?
Normalmente se analiza el volcado en herramientas gráficas (por ejemplo, jvisualvm o Eclipse MAT), porque buscar objetos a mano en un archivo binario es ya de alto nivel y un poco masoquista.

Otras posibilidades de jmap

Ver estadísticas de memoria:

jmap -heap <PID>

Muestra información del heap: tamaño, GC utilizado, estado.

Lista de clases:

jmap -histo <PID>

Muestra estadísticas por clase: cuántos objetos de cada tipo y el tamaño total.

Ejemplo de salida:

# Objeto Cantidad Bytes
1
[C
1200 48000
2
java.lang.String
1000 32000
3
java.util.HashMap
200 12800

Esto ya da una idea: si de repente tiene millones de objetos de algún tipo — hay motivo para reflexionar.

2. jvisualvm: analizador visual de memoria

jvisualvm es una aplicación gráfica incluida en el JDK (mire en la carpeta bin). Permite conectarse a procesos Java locales (y a veces remotos), monitorizarlos en tiempo real, tomar un heap dump, ver estadísticas de memoria, hilos, GC, CPU e incluso perfilar la ejecución del código.

Si le gusta hacer clic con el ratón y ver gráficas bonitas, esta es su herramienta.

Cómo iniciar jvisualvm

En la línea de comandos (o mediante un acceso directo en Windows):

jvisualvm

Se abrirá una ventana en la que verá la lista de todos los procesos Java locales.

Funciones principales de jvisualvm

Monitorización de memoria en tiempo real

  • Seleccione el proceso en la lista de la izquierda.
  • Vaya a la pestaña Monitor.
  • Verá gráficas del uso del heap y de la CPU, así como el número de hilos y de clases.

Ejemplo:

jvisualvm-monitor

Heap Dump (volcado de memoria)

  • En el panel Monitor pulse Heap Dump.
  • A los pocos segundos aparecerá una pestaña con el análisis del volcado.
  • Verá la lista de todas las clases, la cantidad de objetos y su tamaño total.

Búsqueda de objetos «pesados»

  • Ordene por tamaño o por cantidad.
  • Si ve que algún tipo (por ejemplo, ArrayList o String) ocupa demasiada memoria — es motivo para investigarlo.

Análisis de referencias (Reference Graph)

  • Haga clic en una clase: verá quién referencia a los objetos de esa clase.
  • Puede llegar hasta la raíz: por qué el objeto no es eliminado por el recolector de basura.

Análisis de hilos

  • La pestaña Threads muestra todos los hilos y su estado.
  • Se pueden identificar hilos «colgados» o demasiado activos.

Perfilado

  • La pestaña Profiler permite medir qué métodos consumen más tiempo o memoria.
  • Esto ya es un análisis profundo, pero para encontrar fugas de memoria bastan los primeros pasos.

3. Práctica: analizamos una fuga de memoria

Ejemplo de código con fuga

import java.util.ArrayList;
import java.util.List;

public class MemoryLeakDemo {
    // Colección estática: ¡un clásico!
    private static final List<String> bigList = new ArrayList<>();

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 1_000_000; i++) {
            bigList.add("Línea número " + i);
            if (i % 100_000 == 0) {
                System.out.println("Añadidos: " + i);
                Thread.sleep(500); // Damos tiempo para el análisis
            }
        }
        System.out.println("¡Listo! No cierre la aplicación, abra jvisualvm.");
        Thread.sleep(600_000); // 10 minutos — tiempo para el análisis
    }
}

¿Qué está pasando?

  • Creamos una lista estática y añadimos en ella un millón de cadenas.
  • Tras terminar de añadir, el programa se «queda esperando» para que pueda conectarse con herramientas de análisis.

Análisis con jvisualvm

  1. Ejecute el programa.
  2. Abra jvisualvm y seleccione el proceso.
  3. En la pestaña Monitor observe la gráfica de memoria.
    • Si todo va bien, la memoria debería «liberarse» después del GC.
    • Si hay una fuga, la memoria solo crecerá.
  4. Haga un Heap Dump.
  5. Vea qué objetos ocupan más memoria.
    • En nuestro caso — java.util.ArrayList y java.lang.String.
  6. Haga clic en el objeto y vea quién lo referencia.
    • Verá que es el campo estático bigList.

¿Cómo arreglarlo?

  • Elimine los elementos innecesarios de las colecciones y limite su crecimiento.
  • Ponga a null las referencias a objetos pesados cuando ya no se necesiten.
  • No mantenga colecciones grandes en static si no son necesarias de forma permanente.

4. Otras herramientas: Eclipse MAT, jconsole

Eclipse Memory Analyzer (MAT)

Eclipse MAT es una herramienta gratuita pero potente para analizar heap dump. Con ella puede ver qué objetos ocupan memoria y cuáles retienen a otros — el llamado retained set. Esto permite determinar con precisión dónde se esconde la fuga.

La herramienta sabe generar informes detallados sobre objetos sospechosos (leak suspects) y se maneja con calma incluso con volcados gigantes de varios gigabytes.

El funcionamiento es sencillo: tome un volcado de memoria con jmap o jvisualvm, lo abre en MAT, pulse el botón Leak Suspects Report — y obtiene un informe listo en el que ya se resaltan los problemas potenciales.

jconsole

jconsole es una herramienta sencilla y cómoda para observar la JVM en tiempo real. Muestra cuánta memoria se utiliza, cuánta carga tiene la CPU, cuántos hilos están en ejecución y cómo se comporta el recolector de basura.

A diferencia de herramientas más avanzadas como VisualVM, jconsole no analiza heap dump, pero es excelente para un diagnóstico rápido — cuando necesita entender de un vistazo qué está ocurriendo dentro de la aplicación.

5. Errores típicos al analizar memoria

Error n.º 1: hacer el volcado del proceso equivocado. A menudo en la máquina se ejecutan muchas aplicaciones Java y es fácil confundir el PID. Compruébelo con jps y asegúrese de que analiza precisamente su programa.

Error n.º 2: esperar ver una «fuga» donde no la hay. El GC puede no eliminar los objetos de inmediato — a veces la memoria se «libera» solo después de un Full GC. No se alarme si tras una iteración la memoria no se ha liberado — observe la tendencia.

Error n.º 3: no tener en cuenta la influencia de objetos estáticos/en caché. Muchas fugas están relacionadas con que los objetos se almacenan en campos static o en colecciones globales. Compruebe quién referencia a los objetos «pesados» — a menudo es static.

Error n.º 4: no usar el perfilado en tiempo real. Un heap dump está bien, pero a veces es importante observar el crecimiento de la memoria a lo largo del tiempo (gráficas en jvisualvm). Si la memoria crece de forma estable — hay motivo para investigarlo.

Error n.º 5: no eliminar listeners/controladores de eventos. Si se suscribe a un evento pero no se da de baja, el objeto seguirá «vivo» en memoria, incluso si ya no lo utiliza.

Consejo: ¡No tenga miedo de experimentar con las herramientas! Tome volcados, mire las gráficas, haga clic en los objetos — solo así aprenderá a «sentir» la memoria de su programa y a encontrar los problemas rápidamente.

1
Tarea
JAVA 25 SELF, nivel 64, lección 3
Bloqueada
Volcado de memoria con jmap — Instantánea digital del oso 🐻
Volcado de memoria con jmap — Instantánea digital del oso 🐻
1
Tarea
JAVA 25 SELF, nivel 64, lección 3
Bloqueada
Visualización de estadísticas por clases con jmap – Inventario del Zoológico Digital 🐒🐘🐆
Visualización de estadísticas por clases con jmap – Inventario del Zoológico Digital 🐒🐘🐆
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION