Linux · memoria y systemd · Elaine System
Presión de memoria en Linux: diagnóstico con PSI, cgroups y systemd
Diagnostica presión de memoria en Linux con PSI, memoria disponible y límites de cgroup v2 y systemd antes de ajustar un servidor.
La memoria ocupada no basta para explicar una falla
Un servidor puede usar casi toda su RAM y seguir respondiendo bien, o mostrar memoria disponible y aun así sufrir pausas por recuperación de páginas, intercambio o un límite aplicado a un servicio. Para diagnosticar presión de memoria en Linux, relaciona el impacto visible con señales del host y del grupo de control (cgroup) donde corre el proceso.
Este recorrido es de solo lectura: reúne tendencias de PSI, datos de /proc/meminfo, propiedades de systemd, contadores de cgroup v2 y registros del kernel. No cambies MemoryHigh=, MemoryMax= ni archivos del cgroup hasta entender qué señal confirma el problema y qué servicio recibiría el impacto.
1. Identifica presión real con PSI
Pressure Stall Information (PSI) mide cuánto tiempo de ejecución se pierde porque tareas esperan un recurso. En memoria, la línea some refleja periodos donde al menos una tarea no ociosa está detenida; fullregistra periodos donde todas las tareas no ociosas quedan detenidas a la vez. Los campos avg10, avg60 y avg300 resumen ventanas recientes; total acumula tiempo de espera en microsegundos.
cat /proc/pressure/memory
cat /proc/pressure/cpu
cat /proc/pressure/ioNo interpretes un valor aislado como umbral universal. Captura varias muestras durante el incidente y compáralas con latencia, errores y carga habitual. Un aumento sostenido de some indica contención que afecta a parte del trabajo; full persistente señala pausas más severas. La ausencia de PSI en /proc puede indicar que la función no está disponible o expuesta en ese kernel o entorno; no demuestra que el sistema esté sano.
2. Distingue el host de un servicio limitado
Registra la hora y el estado general para alinear las señales con el incidente. MemAvailable estima cuánta memoria podría usarse sin recurrir a intercambio; MemFree por sí sola no representa toda la memoria utilizable, porque Linux mantiene cachés que pueden recuperarse.
date -Is
uptime
free -h
grep -E '^(MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree):' /proc/meminfo
cat /proc/pressure/memoryCompara las muestras durante y fuera del pico. Si baja MemAvailable, crece PSI del host y aumentan síntomas al mismo tiempo, hay evidencia de presión global. Si el host conserva margen pero una aplicación se degrada, revisa sus límites y contadores de cgroup: el problema puede estar acotado a esa unidad, contenedor o slice.
3. Consulta los límites efectivos de systemd
Para una unidad systemd, consulta propiedades sin reiniciarla ni recargar su configuración. Sustituye mi-servicio.service por el nombre real.
systemctl show mi-servicio.service \
-p ControlGroup -p MemoryCurrent -p MemoryPeak \
-p MemoryHigh -p EffectiveMemoryHigh \
-p MemoryMax -p EffectiveMemoryMax \
-p MemorySwapCurrent -p MemorySwapPeakMemoryCurrent y MemoryPeak ayudan a leer el consumo reportado por la unidad. Los valores efectivos consideran límites heredados de slices superiores y restricciones del host. Algunas propiedades dependen de la versión de systemd; si aparecen vacías o desconocidas, confirma la versión y consulta directamente la interfaz cgroup disponible.
systemd documenta MemoryHigh= como control principal: excederlo provoca recuperación directa y ralentización del grupo, sin activar por sí solo el OOM killer. MemoryMax= es el límite rígido y la última barrera; si no se puede contener el uso, puede activarse OOM dentro de la unidad. Por eso, reducir ambos valores para “liberar RAM” puede convertir una degradación en terminaciones de procesos.
4. Lee contadores de cgroup v2
Confirma si el host expone cgroup v2 y consulta la ruta de la unidad en ControlGroup. El punto de montaje y la ruta visible pueden variar dentro de contenedores o namespaces; usa la ubicación real del entorno.
findmnt -t cgroup2
systemctl show mi-servicio.service -p ControlGroup
cat /sys/fs/cgroup/<ruta-de-la-unidad>/memory.current
cat /sys/fs/cgroup/<ruta-de-la-unidad>/memory.high
cat /sys/fs/cgroup/<ruta-de-la-unidad>/memory.max
cat /sys/fs/cgroup/<ruta-de-la-unidad>/memory.events
cat /sys/fs/cgroup/<ruta-de-la-unidad>/memory.pressureEn los límites, max suele indicar que ese control no establece un valor numérico. En memory.events, revisa especialmentehigh, max, oom y oom_kill: registran cruces de límite, intentos de asignación fallidos y procesos terminados por OOM. Los contadores de memory.events son jerárquicos; donde exista memory.events.local, permite separar eventos del cgroup actual de los descendientes.
Estos contadores son acumulativos. Toma dos lecturas con hora, durante una ventana conocida, y calcula qué valores aumentaron. Un número histórico mayor que cero no demuestra que el problema siga activo. Compara tambiénmemory.pressure del cgroup con /proc/pressure/memory: esa diferencia ayuda a separar saturación del host de impacto concentrado en una carga.
5. Busca eventos OOM y correlación temporal
Revisa mensajes del kernel en torno al incidente. La disponibilidad y retención del journal dependen de la configuración del sistema.
journalctl -k --since '30 minutes ago' --no-pager | \
grep -Ei 'out of memory|oom-kill|killed process'Correlaciona la hora con reinicios del proceso, errores de aplicación, eventos de cgroup y alertas de disponibilidad. Una línea de OOM identifica una terminación asociada al agotamiento; no explica por sí sola por qué creció el consumo, qué dependencia originó la carga o si el límite estaba bien elegido. Busca también logs de la aplicación y cambios recientes de tráfico, despliegue, configuración o tamaño de datos.
Patrones útiles para acotar la causa
- PSI del host sube y varios servicios se ralentizan: compara memoria disponible, actividad de swap y cargas concurrentes; evalúa presión global antes de culpar a una unidad.
- Host estable, eventos
highcrecen en una unidad:revisaMemoryHigh, su límite efectivo y la latencia de esa carga. El contador puede aumentar por el control configurado; contrástalo con impacto real. max,oomuoom_killaumentan:relaciona uso, límite y logs. Determina si la unidad, una aplicación o un grupo superior agotó su margen.- Memoria ocupada crece sin presión ni latencia: conserva una serie temporal y revisa el patrón de la aplicación; consumo alto no prueba una fuga ni obliga a reiniciar.
Si PSI no está expuesto, usa series de memoria del host, consumo por cgroup, actividad de swap, registros OOM y métricas de latencia. No mezcles valores de host y contenedor: sus namespaces y límites pueden presentar vistas distintas de los recursos disponibles.
Antes de cambiar un límite
Conserva dos o más muestras con hora, nombre de unidad, versión de kernel y systemd, topología de slices, consumo y límites efectivos. Añade el síntoma del servicio y los eventos observados. Retira nombres de clientes, rutas privadas, tokens y datos de aplicaciones antes de compartir capturas o registros.
Cambiar un límite modifica el comportamiento de una carga: menos margen puede causar throttling u OOM; más margen puede perjudicar a otras unidades. Acordar impacto, responsable, ventana, criterio de reversión y una métrica de éxito antes de editar hace que la intervención sea verificable. Este artículo no propone valores universales ni afirma haber probado comandos en un servidor de cliente.
Fuentes oficiales
- Linux Kernel: Pressure Stall Information (PSI)
- Linux Kernel: interfaz de memoria de cgroup v2
- systemd: control de recursos y límites de memoria
- Linux Kernel: /proc/meminfo
Revisamos estos enlaces el 17 de octubre de 2026. Documentación, requisitos y comportamientos pueden cambiar; confirma la guía aplicable a tu versión y proveedor antes de modificar sistemas.