← Gestión de Memoria Bloque 9 · Intercambio y mapeo de memoria · Tema 40 de 52

Tema 40

Intercambio y espacio de swap

La memoria virtual permite usar más memoria de la que hay (tema 28), y el intercambio es su herramienta más antigua: las páginas que no caben en la RAM se mudan al disco, a un espacio llamado swap. El trueque es brutal —un acceso de cien nanosegundos pasa a costar milisegundos— pero mantiene vivos a los procesos. En este tema verás qué páginas van al swap, cómo se administra en Linux, qué controla swappiness, qué pasa cuando todo se agota (el OOM killer) y lo probarás en un simulador de dos niveles.

1. Qué es el intercambio

La RAM es un recurso finito y todos los procesos compiten por ella. Cuando el gestor necesita marcos y ya no quedan páginas limpias de archivo que descartar (tema 38), toma páginas anónimas —las del heap y la pila— y las escribe en el disco. Ese movimiento se llama swap out, y el viaje de vuelta, cuando alguien toca la página otra vez, es el swap in.

Intercambio (swap) es la técnica que guarda en disco las páginas que no caben en la RAM para liberar marcos, y las devuelve a memoria cuando se vuelven a usar. El espacio de disco reservado para esto se llama espacio de swap.

El efecto es que la memoria disponible ya no termina en la RAM: un conjunto de procesos puede usar hasta RAM + swap de memoria anónima. Es la promesa central de la memoria virtual (tema 28): el programa cree que tiene memoria de sobra, aunque parte de ella viva en un dispositivo miles de veces más lento.

Históricamente, los primeros sistemas intercambiaban procesos completos: un proceso entero salía de la RAM y otro entraba (lo que se llamaba swapping). Los sistemas actuales intercambian páginas individuales —son más flexibles— pero conservan el nombre. El costo del trueque es enorme: un acceso a RAM cuesta unos 100 ns, y volver del swap, unos 10 ms (tema 32). Como el mago que paga sus trucos con años de vida, el sistema gana capacidad y paga con tiempo.

2. Qué páginas van al swap

No todas las páginas son candidatas a mudarse al disco: depende de si existe otra copia de su contenido.

Tipo de páginaEjemplos¿Va al swap?Cómo vuelve
AnónimaHeap (malloc), pila, mapeos anónimosSí. La RAM es su única copia: si se libera el marco sin guardarla, se pierdeLeyendo del swap: provoca un fallo mayor
De archivo, limpiaCódigo, bibliotecas, mmap de archivos sin cambiosNo. Se descarta directamente: el archivo en disco ya es la copia de respaldo (tema 34)Releyendo del archivo; si hay que ir al disco, es un fallo mayor
De archivo, suciammap de archivos con escrituras pendientesNo. Antes de descartarla se sincroniza con su archivoReleyendo del archivo, ya actualizado

Por eso el swap se dimensiona pensando en la memoria anónima: es lo único que no tiene copia en otro lado. Un navegador con 20 pestañas acumula cientos de megabytes anónimos (heap de cada renderizador); un programa que solo lee archivos casi no toca el swap, porque sus páginas se descartan y se releen.

Hay un matiz más: mientras una página recién traída del swap sigue en RAM, el núcleo conserva su ranura en el swap por un tiempo (la «caché de swap»). Si la página no se modifica, puede descartarse más adelante sin escribir nada: la ranura sigue siendo válida. Es uno de los motivos por los que escribir al swap es menos frecuente que leer de él.

3. El espacio de swap en Linux

Linux admite dos formas de swap: una partición dedicada (típica en instalaciones antiguas) o un archivo de swap (swapfile), que se crea dentro de un sistema de archivos existente y es lo habitual hoy. Para ver qué hay activo:

terminal · consultar el swap activo
$ free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       6,2Gi       1,1Gi       412Mi       8,4Gi       8,9Gi
Swap:          2,0Gi       512Mi       1,5Gi
$ swapon --show
NAME      TYPE  SIZE USED PRIO
/swapfile file    2G 512M   -2
$ cat /proc/swaps
Filename                                Type            Size           Used           Priority
/swapfile                               file            2097148        524288         -2

Crear un archivo de swap son cuatro pasos: reservar el archivo, darle permisos solo al dueño, formatearlo como swap y activarlo. Para que se active en cada arranque, se agrega una línea a /etc/fstab.

terminal · crear y activar un archivo de swap
$ sudo fallocate -l 2G /swapfile
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

¿Cuánto espacio asignar? La regla clásica de «el doble de la RAM» ya no se aplica: solo es necesaria si se quiere hibernar (al hibernar, todo el contenido de la RAM se escribe en el swap). Para uso normal alcanza con unos pocos GiB, y muchas distribuciones modernas directamente usan zram: swap comprimido dentro de la propia RAM, más rápido que el disco aunque con menos capacidad (lo verás en la sección 10). También se puede desactivar todo el swap con swapoff -a.

4. Volver del disco: swap in

Traer una página de vuelta es una secuencia que ya conoces del tema 29, con un paso adicional:

  1. Un acceso toca una página que está en swap. El hardware no encuentra la traducción y provoca un fallo de página; como hay que ir al disco, será un fallo mayor (tema 30).
  2. El núcleo consigue un marco. Si hay uno libre, lo usa; si no, primero libera otro (con otro swap out o descartando una página de archivo).
  3. Lee la página desde el swap —el bloque de 4 KiB— y la copia al marco.
  4. Actualiza la tabla de páginas para que la dirección virtual apunte al nuevo marco y reanuda la instrucción que había fallado.

Los costos, puestos en perspectiva:

OperaciónCosto típicoDónde se estudió
Acceso a RAM~100 nsTema 32
Fallo de página menor~2 µsTema 30
Volver del swap (fallo mayor)~10 msTemas 30 y 32

Un solo fallo mayor cuesta tanto como cien mil accesos a memoria. Por eso la regla de oro del rendimiento es que el swap se use poco y tarde: es un colchón de emergencia, no una extensión habitual de la RAM.

5. swappiness: cuánto intercambiar

Cuando el núcleo necesita marcos, tiene dos monedas con las que pagar: descartar páginas de archivo (baratas: quizá estén en caché y no se pierda nada) o mandar páginas anónimas al swap (caras: implican escritura y futura lectura de disco). El parámetro swappiness inclina la balanza.

swappiness es el parámetro del núcleo que decide con qué agresividad se usa el swap, inclinando la elección entre descartar caché de archivos y enviar memoria anónima al disco.

terminal · consultar y cambiar swappiness
$ cat /proc/sys/vm/swappiness
60
$ sudo sysctl vm.swappiness=10
vm.swappiness = 10

Para que el cambio sobreviva al reinicio se escribe en un archivo de /etc/sysctl.d/ (por ejemplo 99-swap.conf con la línea vm.swappiness=10). ¿Cuándo ajustarlo? Los servidores con mucha caché útil (bases de datos, servidores de archivos) suelen bajarlo para no sacrificar caché; en un equipo de escritorio, dejarlo en 60 es razonable. Bajarlo no elimina el problema de fondo: si la memoria no alcanza, el swap se usará igual; solo cambia qué se sacrifica primero.

6. Intercambio e hiperpaginación

El swap tiene un doble filo. Por un lado es un seguro de vida: un pico de memoria que supera la RAM no mata al proceso, solo lo frena. Por otro, hace posible la hiperpaginación (tema 33): si los conjuntos de trabajo no caben, el sistema pasa el día moviendo páginas y cada avance de los procesos cuesta un fallo mayor. El trabajo avanza, pero a paso de tortuga.

Sin swap, en cambio, el desenlace es más abrupto: cuando la RAM se agota no hay colchón y el mecanismo de emergencia es matar procesos (la sección siguiente). Por eso los sistemas modernos prefieren poco swap pero no cero para la mayoría de los casos: suficiente para absorber picos, insuficiente para sostener una hiperpaginación prolongada.

Las señales de que el sistema está en este escenario ya las conoces: la CPU pasa tiempo en espera de disco (wa, id) y el swap se mueve sin parar. En vmstat 1, esas son las columnas si y so.

7. Cuando todo se agota: el OOM killer

Cuando la RAM y el swap están agotados y un proceso pide una página más, el núcleo no puede cumplir. No queda nada que intercambiar ni que descartar. La última línea de defensa es el OOM killer (Out Of Memory killer): el núcleo elige un proceso, lo mata con SIGKILL y libera su memoria para que el resto del sistema siga vivo.

La elección no es aleatoria. Cada proceso tiene una puntuación de «maldad», oom_score, que va de 0 a 1000 y crece con la memoria que ocupa: la víctima habitual es el proceso más tragón. Sobre esa base se puede incidir con oom_score_adj, un ajuste de −1000 a +1000:

terminal · la víctima del OOM killer, en primera persona
$ cat /proc/2785/oom_score
742
$ dmesg | grep -i 'killed process'
[7961.33] Out of memory: Killed process 2785 (chromium) total-vm:15234516kB, anon-rss:6204476kB

En los sistemas actuales el OOM casi nunca es global: los cgroups (y los contenedores, que se apoyan en ellos) tienen su propio límite de memoria, y al alcanzarlo el OOM killer mata un proceso de ese grupo sin tocar el resto de la máquina. En escritorios recientes, además, hay demonios en espacio de usuario (como systemd-oomd) que actúan antes con señales de presión de memoria, para llegar antes que el colapso.

8. El simulador de dos niveles

Este simulador agrega un segundo nivel al modelo de reemplazo: además de los marcos de RAM, hay un espacio de swap en «marcos de disco». Un proceso toca un conjunto de páginas (primero en orden, después en dos vueltas de bucle) y el simulador registra cada acceso: aciertos, fallos menores, fallos mayores y los movimientos entre RAM y swap. Si el conjunto no entra en RAM + swap, el OOM killer aparece.

Simulador · RAM + swap + conjunto de trabajo

ESTADO FINAL

ACCESO POR ACCESO

TOTALES

MedidaValor
Accesos ejecutados
Aciertos
Fallos menores
Fallos mayores (swap in)
Escrituras de swap (swap out)
E/S total de swap (páginas)

9. Qué observar

10. En Linux

La actividad de swap se observa con contadores del sistema. vmstat muestra las columnas si (swap in) y so (swap out) junto a la espera de CPU:

terminal · actividad de swap en vivo
$ vmstat 1 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  2 524288 123456  67584 432100  512  384    12    45  890 1200 32  4 58  6  0
 2  1 524288 121008  67584 431872  768  512    18    62  910 1260 30  5 55 10  0
 1  3 528916 118764  67584 430912 1024  640    25    80  930 1310 28  4 52 16  0
$ grep -E 'pswpin|pswpout' /proc/vmstat
pswpin 148273
pswpout 356102

Y este programa lee la información del swap directamente de /proc, para que puedas consultarla desde C:

infoswap.c
#include <stdio.h>
#include <string.h>

int main(void)
{
    char linea[256];
    FILE *f = fopen("/proc/meminfo", "r");
    if (!f) { perror("/proc/meminfo"); return 1; }

    printf("Swap en /proc/meminfo:\n");
    while (fgets(linea, sizeof linea, f)) {
        if (!strncmp(linea, "SwapTotal:", 10) ||
            !strncmp(linea, "SwapFree:", 9) ||
            !strncmp(linea, "SwapCached:", 11))
            printf("  %s", linea);
    }
    fclose(f);

    f = fopen("/proc/swaps", "r");
    if (!f) { perror("/proc/swaps"); return 1; }

    printf("Swap activo (/proc/swaps):\n");
    int primera = 1;
    while (fgets(linea, sizeof linea, f)) {
        if (primera) { primera = 0; continue; }  /* encabezado */
        printf("  %s", linea);
    }
    fclose(f);
    return 0;
}
terminal · infoswap en ejecución
$ gcc -std=c17 -Wall -Wextra -o infoswap infoswap.c
$ ./infoswap
Swap en /proc/meminfo:
  SwapTotal:       2097148 kB
  SwapFree:        1572860 kB
  SwapCached:            0 kB
Swap activo (/proc/swaps):
  /swapfile                               file		2097148		524288		-2

11. Resumen

12. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué es el swap out y qué es el swap in?

Swap out es escribir una página de la RAM al espacio de swap para liberar un marco; swap in es leerla de vuelta cuando se vuelve a usar.

2. ¿Qué páginas van al swap y cuáles no?

Las anónimas (heap, pila) sí, porque la RAM es su única copia. Las de archivo no: se descartan y se releen del archivo, que es su respaldo.

3. ¿Cuánta memoria puede usar un proceso con swap?

Hasta el total de RAM + el espacio de swap, en lo que respecta a memoria anónima.

4. ¿Qué es el archivo de swap y cómo se crea en Linux?

Un archivo que se usa como espacio de intercambio: fallocate para reservarlo, chmod 600, mkswap para formatearlo y swapon para activarlo.

5. ¿Qué controla swappiness y cuál es su valor por defecto?

Con qué agresividad se usa el swap frente a descartar caché de archivos. Por defecto vale 60.

6. ¿Qué provoca un fallo mayor al volver del swap?

Que la página debe leerse del disco: unos 10 ms, decenas de miles de veces más que un acceso a RAM.

7. ¿Qué hace el OOM killer y a quién elige?

Mata un proceso (con SIGKILL) cuando RAM y swap se agotan. Elige al de mayor oom_score, que crece con la memoria usada; oom_score_adj permite protegerlo o marcarlo como víctima.

8. ¿Por qué se dice que el swap es un seguro, pero también un riesgo?

Seguro: evita el OOM y absorbe picos de memoria. Riesgo: si el conjunto de trabajo no cabe, permite que la hiperpaginación se sostenga y el sistema quede lentísimo.

Para practicar

  1. Ejecuta free -h y swapon --show en tu sistema: ¿hay swap activo? ¿de qué tamaño?
  2. En el simulador, encuentra con 3 marcos de RAM la cantidad de swap mínima para que un conjunto de 6 páginas no termine en OOM.
  3. Compila infoswap.c y compara su salida con free -h.
  4. Provoca hiperpaginación en el simulador (4 páginas, 3 marcos) y anota la E/S por vuelta. ¿Cómo cambia si subes la RAM a 4?
  5. Lee cat /proc/sys/vm/swappiness y explica qué cambiaría en un servidor de archivos ajustarlo a 10.
  6. Investiga si tu distribución usa zram (swapon --show) y calcula cuánta memoria comprimida aporta.
  7. Experimenta con vmstat 1 mientras abres varios programas: ¿aparecen valores en si y so?