Debugging de memoria en Linux: herramientas y técnicas clave

Última actualización: 26 de febrero de 2026
  • Linux ofrece comandos como free, vmstat, ps y top para inspeccionar el uso real de memoria y CPU, diferenciando memoria usada, libre y cacheada.
  • Herramientas como GDB y Valgrind permiten detectar fallos de segmentación, fugas de memoria, accesos ilegales y variables sin inicializar en programas nativos.
  • En entornos .NET Core, la combinación de dotnet-dump, LLDB y SOS facilita el análisis profundo de volcados de memoria tanto en Linux como desde Windows.
  • Un flujo ordenado de diagnóstico que combine métricas del sistema, logs y análisis de volcados reduce drásticamente el tiempo para localizar y corregir problemas de memoria.

Depuración de memoria en Linux

Cuando algo va mal en un servidor Linux, muchas veces la causa está en cómo se está usando la memoria y las herramientas de debugging, pero hasta que no sabes qué mirar, todo parece un caos de números y procesos. Entender qué está pasando en la RAM, cómo se comportan tus programas y cómo capturar volcados de memoria es clave para no ir a ciegas cada vez que aparece un error raro o un segmentation fault.

En este artículo vamos a ver, con bastante detalle y sin rodeos, cómo inspeccionar memoria, depurar programas y analizar volcados en Linux usando comandos del sistema (free, vmstat, /proc/meminfo), depuradores como GDB, analizadores de memoria como Valgrind y utilidades específicas para .NET y otros entornos. La idea es que salgas con un “arsenal práctico” para diagnosticar problemas de memoria y CPU en servidores y entornos de desarrollo profesionales.

Visión general: memoria en Linux y por qué no hay que obsesionarse con el 100%

En un servidor Linux, la memoria RAM actúa como almacén rápido para datos y código que el sistema necesita reutilizar en breve. Acceder a RAM es muchísimo más veloz que tirar del disco, así que el kernel aprovecha para usarla como caché de archivos, buffers y páginas de memoria que podrían hacer falta de nuevo en poco tiempo.

En el contexto de un servidor web con Apache o Nginx, o de un servidor de bases de datos como MySQL o MariaDB, saber cuánta memoria está en uso, cuánto queda libre y qué parte está en caché es vital para dimensionar correctamente los servicios y comprender namespaces y cgroups. De hecho, herramientas de optimización como MySQLTuner toman estos datos (y otros) para sugerir ajustes de buffers, cachés y conexiones.

Conviene tener clara una idea que suele chocar al principio: la memoria RAM está diseñada para estar ocupada. Que veas un 90% o incluso un 100% de uso no es necesariamente un drama; Linux rellena RAM con caché de disco para acelerar el sistema. Lo preocupante de verdad es cuando empiezan a aparecer errores de falta de memoria, procesos que mueren con OOM (Out Of Memory) o servicios que se caen, no simplemente que el gráfico marque “muy usado”.

Solo tiene sentido saltar a optimizar agresivamente si notas que el servidor se vuelve inestable, lento o corta servicios por sobreuso de memoria, o si sabes que se van a venir picos de tráfico que podrían reventar los recursos actuales.

Comandos básicos para inspeccionar memoria en Linux

Herramientas de memoria en Linux

El primer paso para depurar problemas de memoria es tener claro qué cantidad de RAM total tienes y cómo se reparte entre memoria usada, libre, caché y swap. Linux ofrece varias utilidades para esto, cada una con un nivel de detalle distinto.

Comando free: visión rápida de RAM y swap

El comando más utilizado para un vistazo rápido es free, especialmente con el parámetro -h para mostrar tamaños en formato legible: Para profundizar en interpretación y optimización de estas métricas consulta optimizar estadísticas de memoria.

free -h

La salida típica te muestra, en pocas líneas, la memoria total, usada, libre, compartida, buffers y caché, tanto para la RAM como para la memoria de intercambio (swap). Verás algo del estilo:

total   used   free   shared  buffers  cached
Mem:   2.0G   1.5G   470M    300M     0B      414M
-/+ buffers/cache: 1.1G   885M
Swap:  0B     0B    0B

La línea -/+ buffers/cache es especialmente útil porque te indica la memoria realmente utilizada por procesos (descontando buffers/caché) y la que está potencialmente disponible para nuevas aplicaciones. Mucha gente ve poca “memoria libre” en la primera línea y se asusta, cuando en realidad gran parte está sólo cacheada y puede ser reutilizada sin drama.

vmstat: memoria activa, inactiva y métricas de sistema

Cuando necesitas algo más detallado, vmstat da una foto más técnica del sistema. Con:

vmstat -s -S M

obtendrás una lista con la memoria total, usada, libre, activa, inactiva, buffers, memoria de swap, etc. Por ejemplo:

2048 M total memory
1582 M used memory
1124 M active memory
 406 M inactive memory
 465 M free memory
 0 M buffer memory
 407 M swap cache
 0 M total swap
 0 M used swap
 0 M free swap

El concepto de memoria inactiva es interesante: se trata de memoria que se considera en uso pero que no está asociada a procesos activos, por lo que a efectos prácticos se comporta como memoria recuperable por el sistema. Esto ayuda a entender por qué Linux puede parecer que “lo ocupa todo” pero, en realidad, tiene margen para liberar cuando haga falta.

/proc/meminfo: el detalle crudo del kernel

Si quieres todos los detalles que maneja el kernel, siempre puedes echar un ojo al archivo /proc/meminfo:

cat /proc/meminfo

Este fichero incluye decenas de campos relacionados con la gestión interna de la memoria: memoria total, libre, buffers, caché, slab, hugepages, memoria disponible, etc. Es muy útil para herramientas automatizadas y scripts de monitorización, aunque leído a pelo resulta algo menos amable que free o vmstat y requiere saber bien qué significa cada campo.

Paneles de control y su “realidad paralela”

Si administras un servidor con paneles como cPanel, Plesk, VestaCP o Webmin, verás que suelen mostrar gráficos de memoria usada, libre y cacheada desde una interfaz web. Estos datos son cómodos, pero hay que tener presente que se actualizan cada cierto intervalo y a veces no reflejan el estado exacto en tiempo real. Para diagnósticos serios y debugging fino, conviene ir siempre a la terminal y a los comandos nativos.

Debugging de procesos y memoria con herramientas de sistema

Una vez sabes cuánta memoria hay y cómo se usa a grandes rasgos, el siguiente paso es localizar qué procesos están consumiendo recursos de forma anómala y analizar su comportamiento. Aquí entran en juego utilidades clásicas como ps, top, htop, strace, ltrace, y también comandos de red y disco que ayudan a descartar cuellos de botella.

ps, top y htop: radiografía de procesos y CPU

El comando ps muestra los procesos activos. Combinado con filtros y ordenación, permite localizar rápidamente qué se está comiendo la CPU:

ps aux --sort=-%cpu | head

Con esto ves los procesos ordenados por porcentaje de CPU, junto con memoria usada, usuario y comando. Es ideal como foto fija para encontrar el sospechoso principal cuando el servidor va justo de recursos; dominar la terminal ayuda a actuar rápido.

  Guía definitiva de los mejores IDE para programar: comparativa y consejos

Por otro lado, top y su variante más visual htop ofrecen una vista en tiempo real de procesos, consumo de CPU, memoria, estado (R, S, D, etc.) y el load average. Al arrancar top con:

top -o %CPU

puedes centrarte en qué procesos ocupan más CPU. Más allá de los números, es importante fijarse en patrones:

  • Procesos en estado R (running) que se quedan pegados arriba mucho tiempo.
  • Cambios bruscos en el load average que indiquen picos de carga recientes.
  • Reparto de CPU en %us, %sy y %wa (tiempo de usuario, sistema y espera de I/O).
  • Si el proceso problemático es un servicio del sistema, un usuario concreto o un demonio.
  • Si el consumo es estable o sube y baja a golpes, lo que puede apuntar a tareas en batch o tráfico irregular.

Un valor de %wa (I/O wait) muy alto es una pista de que el cuello de botella quizá no está en la CPU, sino en el disco o subsistema de almacenamiento.

Revisión de hilos de un proceso: top -H

Para aplicaciones con múltiples hilos (Java, Python, Node, etc.), no basta con saber qué proceso consume CPU; interesa ver qué hilo concreto está desbocado. Con:

top -H -p PID

obtienes el detalle de cada thread dentro del proceso. Si uno de ellos aparece al 100% y el resto están tranquilos, es probable que haya un bucle infinito, un bloqueo extraño o una sección crítica mal planteada en esa parte del código.

Prioridad de procesos: nice y renice

En caso de que un proceso intenso sea legítimo pero quieras que no arrase con el resto del sistema, puedes jugar con la prioridad (niceness). Los comandos nice y renice permiten arrancar procesos con menor prioridad o reajustar la de uno que ya está corriendo, de modo que el kernel les asigne menos tiempo de CPU frente a otras tareas críticas.

Otros comandos clave: pidof, kill, strace y ltrace

Cuando el sistema está bajo presión, es útil poder localizar y controlar procesos de forma rápida:

  • pidof: obtiene el PID de un proceso a partir de su nombre, perfecto para scripts o intervenciones rápidas.
  • kill: envía señales a procesos (TERM, KILL, etc.), ya sea para apagar ordenadamente o cortar por lo sano si se han quedado colgados.
  • strace: muestra las llamadas al sistema que realiza un proceso; ideal para ver en qué está bloqueado (lecturas de disco, sockets, etc.).
  • ltrace: similar a strace, pero centrado en llamadas a librerías, útil para depurar problemas de uso de APIs compartidas.

Estas herramientas no solo sirven para cazar fugas de memoria o bloqueos, también se usan mucho en ciberseguridad, análisis forense y debugging de comportamiento extraño de binarios.

Comandos para ficheros y disco: lsof, df, du, locate

Cuando sospechas que hay algo raro con el almacenamiento (por ejemplo, muchos ficheros abiertos o discos llenos), entran en juego otros comandos:

  • lsof: lista los ficheros abiertos por un proceso, útil para encontrar fugas de descriptores o archivos que impiden desmontar un sistema de ficheros.
  • df: muestra el espacio libre en disco por sistema de ficheros, imprescindible para descartar discos al 100% que causan fallos en cascada.
  • du: calcula el espacio usado por directorios, muy útil para localizar carpetas que crecen sin control (logs, backups, etc.).
  • locate: permite buscar un fichero por nombre usando una base de datos indexada, más rápido que find en muchas situaciones.

Comandos de red para diagnóstico: nc, netstat, ab, tcpdump, wireshark, nmap

Muchas veces, los problemas de rendimiento y memoria vienen acompañados de cuellos de botella en red o ataques, así que conviene tener a mano algunas herramientas básicas:

  • nc (netcat): una auténtica navaja suiza de red; abre sockets, envía y recibe datos, permite pruebas de servicios, incluso túneles improvisados.
  • netstat: muestra conexiones activas, sockets en escucha y estadísticas de red, útil para ver si hay muchísimas conexiones a un puerto concreto.
  • ab (Apache Benchmark): genera carga contra un servidor web para medir tiempos de respuesta y comportamiento bajo estrés.
  • tcpdump y Wireshark: capturan paquetes de red para analizar tráfico en profundidad; tcpdump en consola, Wireshark con interfaz gráfica.
  • nmap: escáner de puertos y servicios, muy usado tanto para auditorías de seguridad como para comprobar la superficie de exposición de un servidor.

GDB: el depurador clásico para errores de memoria y fallos en tiempo de ejecución

Cuando un programa en Linux casca con un segmentation fault u otro fallo gordo, el siguiente paso lógico es usar un buen depurador. La herramienta estrella en el mundo GNU es GDB (GNU Debugger), que permite inspeccionar el estado interno de un programa, detenerlo donde quieras, ver variables, memoria y seguir la ejecución paso a paso.

GDB fue diseñado originalmente para programas en C y C++, pero se ha extendido a otros lenguajes como Rust o incluso Assembly, y al manejo de rutas de librerías como LD_LIBRARY_PATH. Es fundamental en desarrollo, pero también en ciberseguridad, donde se usa para hacer ingeniería inversa, buscar vulnerabilidades y desarrollar o depurar exploits.

Arrancar GDB y ejecutar un programa

Para usar GDB con un ejecutable, es recomendable compilar el programa con información de depuración usando la opción -g de GCC:

gcc -g -Wall programa.c -o programa

Después lo lanzas con:

gdb programa

Dentro de GDB, el programa aún no está corriendo. Puedes iniciarlo con:

  • run: arranca el programa con los argumentos que quieras.
  • start: igual que run, pero se detiene al comienzo de la función main.

Si tienes un ejecutable llamado, por ejemplo, suma y quieres ver cómo procesa sus argumentos, entrarías en GDB y luego usarías run 3 5 para lanzarlo con esos parámetros desde el depurador.

Breakpoints y watchpoints: parando el programa donde interesa

Los breakpoints son puntos de parada en el código fuente: cuando la ejecución llega ahí, el programa se detiene y puedes inspeccionar todo el estado interno. En GDB se definen con el comando:

break lugar

donde “lugar” puede ser un nombre de función, número de línea o archivo:línea. Un ejemplo típico sería:

break main

para que GDB se frene justo al entrar en la función principal. Cuando el programa se para en un breakpoint, puedes ver código con l (listar), consultar variables y moverte por la pila de llamadas.

Los watchpoints funcionan distinto: en vez de detenerse en un punto del código, se detienen cuando cambia el valor de una variable. Son muy útiles para detectar corrupciones de memoria o modificaciones inesperadas en estructuras críticas sin tener que inundar el código de prints.

Control fino del flujo: step, next, continue, finish

Una vez el programa está detenido en un breakpoint, tienes varias formas de avanzar:

  • step: ejecuta la siguiente línea y entra dentro de las funciones llamadas.
  • next: ejecuta la siguiente línea sin entrar en las funciones (las corre “de golpe”).
  • continue: reanuda la ejecución hasta el próximo breakpoint o hasta que el programa termine.
  • finish: continúa hasta que la función actual retorne y se vuelva al punto desde donde fue llamada.
  Guía completa sobre Keras: qué es y cómo funciona

Esto permite inspeccionar código sospechoso paso a paso, sin tener que “tragarte” todo el programa. Un truco cómodo: en GDB, pulsar Enter repite el último comando, ideal para ir haciendo muchos next o step seguidos sin teclear tanto.

Pila de llamadas y frames: ver cómo hemos llegado hasta aquí

Para entender por qué se ha producido un fallo en cierto punto, es vital ver qué funciones se fueron llamando hasta llegar ahí. La estructura que guarda esta información es la pila de llamadas (call stack). GDB ofrece varios comandos para manejarla:

  • bt (backtrace): muestra la pila completa, con la lista de funciones anidadas y los números de frame.
  • up: sube un nivel en la pila, al punto que llamó a la función actual.
  • down: baja un nivel, hacia la función que se estaba ejecutando.
  • fr (frame): muestra el frame actual o te permite cambiar a otro indicando su número.

Con esto puedes situarte en distintos niveles de la llamada (por ejemplo, saltar de una función interna a main) y ver cómo estaban las variables en cada sitio.

Interacción con la memoria: set, return, backtrace y x

Una de las grandes ventajas de GDB es que permite leer y modificar memoria en caliente mientras el programa está parado. Algunas operaciones útiles son:

  • set: cambia el valor de una variable durante la ejecución, ideal para probar escenarios sin recompilar.
  • return valor: fuerza que la función actual devuelva el valor indicado, sin seguir ejecutando su código.
  • backtrace: ya visto, para mostrar la pila de llamadas actual.
  • x: examina contenido de memoria a partir de una dirección, con distintos formatos y tamaños (por ejemplo, x/4xw 0x7fffffffe000 para ver cuatro palabras en hexadecimal).

Con estas opciones puedes replicar errores, comprobar si una entrada peligrosa produce overflow o inspeccionar estructuras de datos complejas en la pila o el heap.

Debugging post-mortem con core dumps

Linux puede generar un archivo core cuando un proceso muere por una señal como SIGSEGV. Ese archivo contiene el estado completo del proceso en el momento del crash: memoria, registros, pila, etc. Para activarlos en una sesión basta con:

ulimit -c unlimited

Y para habilitarlos de forma más permanente para usuarios, se puede editar /etc/security/limits.conf y añadir una línea del estilo:

* soft core unlimited

Cuando un programa crashea, se genera un fichero llamado normalmente core en el directorio de trabajo. Puedes analizarlo luego con GDB así:

gdb ejecutable core

Esto te permite hacer un análisis post-mortem casi como si el programa siguiera vivo, ideal cuando el fallo no es fácilmente reproducible a demanda.

Valgrind: cazando fugas y errores de memoria

Para muchos problemas de memoria en C/C++ (y similares), GDB no es suficiente, porque no está diseñado para detectar automáticamente lecturas ilegales, fugas o usos de memoria sin inicializar. Ahí es donde entra Valgrind, un sistema de depuración y perfilado que emula el procesador y monitoriza cada acceso a memoria.

Valgrind incluye varias herramientas, pero la más usada es Memcheck, que reemplaza el gestor de memoria estándar de C por uno propio con zonas de protección alrededor de los bloques asignados. Gracias a esto puede detectar:

  • Uso de memoria sin inicializar (variables que se usan antes de asignarles valor).
  • Lecturas/escrituras tras hacer free (use-after-free).
  • Accesos fuera de los límites de un bloque de memoria.
  • Fugas de memoria (malloc sin free, punteros perdidos, etc.).

Ejemplo sin errores: programa “limpio” bajo Memcheck

Supongamos que compilas un pequeño “hola mundo” con información de depuración:

gcc -Wall -gstabs valgrind_hello_good.c -o valgrind_hello_good

Si lo ejecutas bajo Valgrind con:

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_good

obtendrás una traza donde, al final, la ERROR SUMMARY indica 0 errores y no se reportan fugas. Esto valida que, al menos desde el punto de vista de Memcheck, el programa no presenta anomalías de memoria.

Detectar fugas de memoria (leaks)

Si modificas el código para hacer un malloc sin free (por ejemplo, reservando un byte y nunca liberándolo) y recompilas:

gcc -Wall -gstabs valgrind_hello_bad.c -o valgrind_hello_bad

al ejecutar:

valgrind --tool=memcheck --leak-check=full -v ./valgrind_hello_bad

Valgrind te mostrará un HEAP SUMMARY con “in use at exit” distinto de cero, indicando la cantidad de memoria no liberada. Además, en la sección “definitely lost” verás el número de bytes y bloques fugados, junto con la traza de llamadas que origina el leak (función, archivo y línea de código).

Para casos más elaborados, donde se filtran, por ejemplo, 100 bytes en una función leak(), la salida de Valgrind te señalará claramente el malloc problemático, permitiendo añadir el free correspondiente y verificar después que el resumen vuelve a cero fugas.

Escrituras ilegales y accesos fuera de rango

Otro tipo de error típico que Memcheck detecta son las escrituras en direcciones no válidas, por ejemplo, escribir en la posición de memoria 0 (NULL) o más allá del final de un array. Si compilas un programa que hace una escritura ilegal:

gcc -gstabs -Wall valgrind_illegal_read_write.c -o valgrind_illegal_read_write

y lo ejecutas con:

valgrind -v ./valgrind_illegal_read_write

verás mensajes del tipo:

Invalid write of size 4
at 0x80483C4: main (valgrind_illegal_read_write.c:8)
Address 0x0 is not stack'd, malloc'd or (recently) free'd

Con esto sabes exactamente dónde se produjo la escritura ilegal y qué tamaño tenía, algo que en ejecuciones normales suele manifestarse como un simple “Segmentation Fault” sin más pistas.

Variables sin inicializar y dependencias de su valor

Memcheck también avisa cuando una decisión de control depende de una variable no inicializada. Si compilas un programa con una variable local que nunca se inicializa y se usa en un if:

gcc -gstabs -Wall valgrind_unitialized.c -o valgrind_unitialized

y lo corres con:

valgrind -v --track-origins=yes ./valgrind_unitialized

la salida contendrá algo como:

Conditional jump or move depends on uninitialised value(s)
at 0x80483F2: main (valgrind_unitialized.c:9)
Uninitialised value was created by a stack allocation
at 0x80483EA: main (valgrind_unitialized.c:7)

El parámetro –track-origins=yes ayuda a localizar dónde se creó por primera vez la variable sin inicializar, lo que agiliza mucho la corrección del código.

Mal uso de free y detección de errores en el heap

Valgrind también comprueba que free se llame solo sobre punteros válidos. Si intentas liberar memoria que no proviene de malloc, o si haces doble free sobre el mismo bloque, obtendrás mensajes del estilo:

Invalid free() / delete / delete[] / realloc()
at 0x402B06C: free (...)
by 0x8048449: main (valgrind_illegal_free.c:11)

En muchos casos incluso te indica que la dirección sobre la que llamas a free está justo después de un bloque ya liberado, lo que permite identificar errores de cálculo de punteros o dobles liberaciones.

  systemd 259: cambios clave y requisitos del sistema

En resumen, Valgrind es una herramienta imprescindible cuando sospechas de memory leaks, use-after-free o corrupción de memoria en programas nativos, y su uso combinado con GDB da una visión muy potente del estado interno de las aplicaciones.

Volcados de memoria (core dumps) y análisis en Linux y Windows

En aplicaciones modernas, especialmente en .NET Core, el análisis de problemas complejos de memoria o rendimiento suele implicar la captura de volcados de memoria (dumps) para analizarlos con calma en otra máquina. Estos volcados congelan el estado del proceso en un momento concreto, igual que un core dump tradicional.

Análisis de volcados de .NET en Linux con dotnet-dump y LLDB

En entornos .NET Core en Linux, una de las herramientas recomendadas es dotnet-dump. Tras capturar un volcado, se puede comenzar el análisis con:

dotnet-dump analyze <dump-file>

Es importante que el análisis se haga en una máquina con la misma arquitectura y distribución Linux que el entorno donde se generó el volcado. dotnet-dump está orientada a código gestionado de .NET; para analizar también código nativo (C/C++), es más apropiado usar LLDB junto con la extensión SOS.

LLDB permite depurar tanto código gestionado como nativo, y con la ayuda de dotnet-sos puedes instalar la extensión SOS que aporta comandos específicos para .NET. Para poder cargar correctamente un volcado .NET Core, LLDB y SOS necesitan ciertos binarios del entorno donde se creó el dump:

  1. libmscordaccore.so
  2. libcoreclr.so
  3. dotnet (el host usado para iniciar la aplicación)

Normalmente estos binarios se pueden descargar con la herramienta dotnet-symbol. Si se trata de una build privada o no están en el servidor de símbolos, siempre queda la opción de copiarlos desde la máquina original. Si los binarios no están junto al archivo de volcado, puedes usar en LLDB/SOS:

  • setclrpath <ruta> para indicar dónde están los binarios de .NET Core.
  • setsymbolserver -directory <ruta> para especificar la ubicación de los símbolos.

Una vez tienes todo lo necesario, cargas el volcado en LLDB indicando el host de dotnet como ejecutable a depurar:

lldb --core <dump-file> <host-program>

Aquí <dump-file> es la ruta al volcado y <host-program> suele ser el binario dotnet, salvo que se trate de una aplicación self-contained, en cuyo caso sería el propio ejecutable de la app (sin la extensión .dll).

Dentro de LLDB, a menudo es necesario configurar el servidor de símbolos correcto con setsymbolserver -ms para usar el servidor de Microsoft, o setsymbolserver -directory <ruta> para un directorio local, y ejecutar loadsymbols para cargar los símbolos nativos. A partir de ahí, puedes usar los comandos SOS habituales para analizar el heap gestionado, hilos, excepciones, etc.

Análisis de volcados de Linux desde Windows

Los volcados generados en Linux no están limitados a analizarse en ese mismo sistema; también se pueden abrir desde Windows con herramientas como Visual Studio, WinDbg o de nuevo dotnet-dump. Las capacidades varían:

  • Visual Studio: permite depurar volcados con mezcla de código nativo y gestionado, con una interfaz gráfica muy cómoda. Es recomendable revisar la guía específica de depuración de volcados de memoria de Visual Studio.
  • WinDbg: soporte avanzado para dumps de usuario, incluyendo volcados de Linux con un flujo similar al de Windows. Debes usar la versión x64 de WinDbg para volcados de entornos Linux x64 o Arm64, y la versión x86 para volcados x86.
  • dotnet-dump en Windows: se usa igual que en Linux, con dotnet-dump analyze, recordando escoger la versión x64 o x86 de la herramienta acorde a la arquitectura del volcado.

Diagnóstico profesional de alto consumo de CPU y memoria

Más allá de herramientas puntuales, depurar memoria en Linux suele implicar un flujo de trabajo ordenado para no ir disparando a lo loco. Un esquema práctico para servidores es el siguiente:

  • Mirar top para detectar patrones de carga y procesos sospechosos.
  • Confirmar con ps los procesos que más CPU y memoria usan.
  • Ver si el consumo es lógico (compilaciones, batch, indexados) o huele a comportamiento anómalo.
  • Analizar hilos con top -H -p PID cuando se trata de procesos multi-hilo.
  • Revisar logs del servicio con journalctl o tail.
  • Comprobar si el problema es realmente CPU o se esconde en I/O de disco usando iostat.

Para distinguir si el cuello está en CPU o en disco, iostat -xz 1 3 es de gran ayuda: si ves discos con utilización alta y tiempos de espera largos, junto con un %wa elevado en top, probablemente el problema no sea la CPU sino el almacenamiento.

Aplicando este flujo, es más fácil diagnosticar casos como:

  • Bots o tráfico malicioso disparando procesos php-fpm y saturando el servidor web.
  • Un microservicio Java con un hilo en bucle infinito consumiendo un core entero.
  • Un proceso Python que parece CPU-bound pero en realidad está bloqueado esperando disco en cada iteración de un bucle.

Combinando herramientas de sistema (ps, top, vmstat, free), depuradores (GDB, LLDB, dotnet-dump), analizadores de memoria (Valgrind) y comandos de red y disco, puedes crear una forma de trabajar en la que los problemas de memoria y rendimiento en Linux dejen de ser una caja negra y se conviertan en algo que, con método y paciencia, se identifica y corrige con bastante precisión.

monitor de sistema avanzado para linux
Artículo relacionado:
Monitor de sistema avanzado para Linux: guía completa

Tabla de Contenidos