vmmem consume mucha RAM: cómo ponerle un tope en WSL2
En pocas palabras: vmmem consume tanta RAM porque la VM de WSL2 mantiene en caché los archivos de docker build, npm install y Git y no los devuelve a Windows. Se arregla fijando memory=8GB, processors=4 y swap=4GB en %UserProfile%\.wslconfig y ejecutando wsl –shutdown para aplicar el cambio.
Cuando vmmem consume mucha RAM en Windows 11, la causa es la VM de WSL2: Linux guarda en caché los archivos de docker build, npm install y Git, y no devuelve esa memoria a Windows. La solución es fijar un tope en .wslconfig y ejecutar wsl –shutdown.
vmmem (o vmmemWSL) es el proceso que el Administrador de tareas de Windows 11 muestra para la máquina virtual liviana de Hyper-V donde corre el kernel Linux de WSL2 y el backend de Docker Desktop. Su cifra de memoria es la RAM que Windows le entregó a esa VM, no lo que usan tus contenedores en este momento. Se controla desde el archivo global %UserProfile%\.wslconfig.
En este artículo:
- En 30 segundos
- ¿Por qué vmmem consume mucha RAM aunque pares los contenedores?
- ¿Cómo limitar la memoria de WSL2 con el archivo .wslconfig?
- ¿Cómo aplico el cambio y compruebo que el límite de RAM de WSL2 funciona?
- ¿Sirven autoMemoryReclaim y drop_caches para liberar RAM sin reiniciar WSL?
- ¿Cómo recupero el espacio del disco ext4.vhdx de Docker en WSL2?
- ¿Qué está confirmado y qué falta verificar?
- Errores comunes
- Preguntas Frecuentes
- Conclusión
- Fuentes
En 30 segundos
- Causa: la page cache de Linux se infla con builds y gestores de paquetes, y Hyper-V no recupera esa memoria cuando el trabajo termina.
- Tope por defecto: según Microsoft Learn, memory vale el 50% de la RAM total de Windows, o sea 16 GB en una máquina de 32 GB.
- Arreglo de fondo: memory=8GB, processors=4 y swap=4GB en la sección [wsl2] de .wslconfig, más wsl –shutdown para aplicarlo.
- Duplicado en la fuente: la guía de dev.to repite autoMemoryReclaim con dos valores distintos (gradual y dropcache) en dos secciones.
- Disco aparte: el ext4.vhdx no se achica solo; se compacta con diskpart después de limpiar Docker.
¿Por qué vmmem consume mucha RAM aunque pares los contenedores?
Porque WSL2 corre un kernel Linux real dentro de una VM liviana de Hyper-V, y Linux guarda en la page cache cada archivo que lee durante un docker build, un npm install o una operación de Git sobre un repo grande. Según la guía de GearFlow Lab en dev.to, cuando el trabajo termina Linux marca esa memoria como disponible para sí mismo, pero no se la devuelve a Hyper-V, así que Windows la sigue viendo ocupada.
Hacés el build, mirás el Administrador de tareas, cerrás la terminal, cerrás VS Code, parás los contenedores, y vmmemWSL sigue ahí con 20 GB como si nada, porque Linux nunca le avisó a Windows que esa memoria ya no hacía falta. La fuente lo resume con el principio de Linux “Free RAM is wasted RAM”.
El caso que muestra la fuente: vmmemWSL con 24.180,4 MB (88%) y Docker Desktop con apenas 412 MB. Es un ejemplo ilustrativo del autor, no una medición propia.
Sobre el límite por defecto, Microsoft Learn documenta que memory vale el 50% de la RAM total de Windows. La guía de dev.to agrega un techo de 32 GB y un 80% en builds viejas de Windows. Eso no aparece en la documentación oficial que revisamos, así que tomalo como dato no verificado.
¿Cómo limitar la memoria de WSL2 con el archivo .wslconfig?
Creá el archivo %UserProfile%\.wslconfig, que según Microsoft Learn guarda la configuración global de WSL2 y se lee al arrancar la VM. Apretá Win + R, escribí notepad %UserProfile%\.wslconfig, aceptá crear el archivo y pegá este bloque, ya corregido respecto de la fuente:
[wsl2]
memory=8GB
processors=4
swap=4GB
[experimental]
sparseVhd=trueEsto se conecta con lo que analizamos en una alternativa a Docker que consume menos RAM.
Si no tocás nada, Microsoft Learn documenta este valor por defecto:
- memory: 50% de la RAM total de Windows.
¿Qué número le ponés a memory? La guía de dev.to propone esta tabla. Es una regla práctica del autor, no una recomendación oficial de Microsoft.
| RAM física | memory sugerido | swap sugerido |
|---|---|---|
| 16 GB | 4 GB o 6 GB | 2 GB |
| 32 GB | 8 GB o 12 GB | 4 GB |
| 64 GB o más | 16 GB o 24 GB | 8 GB |

Ojo con pasarte de rosca. Un memory muy bajo puede provocar errores de falta de memoria (OOM) en builds pesados, y el swap sirve para amortiguar esos picos. Si compilás imágenes grandes, arrancá por el valor alto de tu fila y bajá de a poco.
¿Cómo aplico el cambio y compruebo que el límite de RAM de WSL2 funciona?
Abrí PowerShell y ejecutá wsl --shutdown. Reiniciar solo Docker Desktop no alcanza (spoiler: no recarga nada), porque .wslconfig se lee cuando arranca la VM.
Microsoft Learn habla de la “regla de los 8 segundos”: el subsistema tiene que parar por completo antes de relanzarlo. Con wsl --list --running confirmás que no queda ninguna distribución activa. Tené presente que wsl --shutdown corta todas las distros; para una sola, usá wsl --terminate <nombre>.
Después abrí WSL o Docker Desktop y corré free -h dentro de Linux. Con memory=8GB y swap=4GB, el ejemplo de la fuente muestra un total de 7,8 Gi y 4,0 Gi de swap. Complementá con nuestra guía sobre herramientas de IA y GPU.
Una propuesta editorial para verificar, que no sale de la fuente ni probamos nosotros: después del reinicio, corré tu build habitual y mirá vmmemWSL en el Administrador de tareas. Si se va muy por encima del tope que fijaste, sospechá que el archivo no se leyó. Si .wslconfig tiene un error de formato, puede que WSL arranque igual sin aplicarlo, y por eso conviene chequear siempre con free -h.
¿Sirven autoMemoryReclaim y drop_caches para liberar RAM sin reiniciar WSL?
Sirven como parche, no como solución de fondo. La guía de dev.to menciona autoMemoryReclaim con los valores gradual y dropcache, y ubica sparseVhd en [experimental]. El tope de memory sigue siendo lo que te protege.
La guía de dev.to comete un error acá: pone autoMemoryReclaim=gradual en [wsl2] y lo repite en [experimental] con dropcache, dos valores distintos para la misma clave. Si copiás ese bloque tal cual, el archivo queda ambiguo. Usá el de arriba.
Para limpiar a mano entre dos builds seguidos, la fuente propone este comando:
sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches"
# alias opcional en ~/.bashrc o ~/.zshrc
alias dropmem='sudo sh -c "sync; echo 3 > /proc/sys/vm/drop_caches" && free -h'La fuente promete liberar gigabytes en menos de 500 ms. No hay medición que lo respalde, así que no lo damos por hecho. Mi lectura: es una “solución” para el apuro, porque Linux vuelve a llenar la caché en el próximo build.
¿Cómo recupero el espacio del disco ext4.vhdx de Docker en WSL2?
Primero limpiás Docker por dentro y después compactás el disco virtual con diskpart. El ext4.vhdx es disco, no RAM: la caché de BuildKit y las imágenes inflan ese archivo en tu unidad, y borrar imágenes no lo achica solo. Ya lo cubrimos antes en guía para automatizar tareas con scripts.
docker builder prune -a -f
docker system prune -aLa fuente agrega --volumes al segundo comando. Pensalo dos veces: borra los volúmenes sin uso, y ponele que en uno de ellos tenías los datos de desarrollo de Postgres (ejemplo hipotético, pero pasa). Corré primero sin esa opción.
Con el espacio liberado, cerrá WSL y compactá. Abrí PowerShell como administrador:
wsl --shutdown
diskpart
select vdisk file="C:\ruta\completa\ext4.vhdx"
attach vdisk readonly
compact vdisk
detach vdisk
exitPara Docker Desktop, la fuente indica %LOCALAPPDATA%\Docker\wsl\data\ext4.vhdx. Verificá la ruta real en tu equipo, porque puede variar según la versión de Docker Desktop. En diskpart conviene escribir la ruta completa. Y hacé un backup antes de compactar.
¿Qué está confirmado y qué falta verificar?
Confirmado en la documentación de Microsoft
- .wslconfig es global: vive en %UserProfile%\.wslconfig y aplica a todo WSL 2.
- Se lee al arrancar la VM: hay que esperar a que el subsistema pare por completo.
- Valor por defecto: memory al 50% de la RAM.
Sin verificar
- Techo de 32 GB y 80% en builds viejas: solo lo dice dev.to.
- Requisito de Windows 11 23H2 para autoMemoryReclaim: lo afirma la fuente; no lo contrastamos.
- Liberación en 500 ms y “gigabytes”: afirmaciones sin medición.
- Tabla de dimensionamiento: criterio del autor, no de Microsoft.
Errores comunes
- Reiniciar solo Docker Desktop. No recarga .wslconfig. Corrección:
wsl --shutdown. - Copiar la config de dev.to sin revisar. Tiene autoMemoryReclaim duplicado con dos valores distintos. Corrección: no repetir la clave.
- Correr prune con –volumes de memoria. Borra datos de desarrollo. Corrección: listá tus volúmenes antes.
- Fijar memory demasiado bajo. Los builds pesados fallan por OOM. Corrección: subí el valor o el swap.
- Esperar que el VHDX se achique tras el prune. No pasa solo. Corrección: compactá con diskpart.
Preguntas Frecuentes
¿Dónde se crea el archivo .wslconfig?
En la carpeta de tu usuario de Windows, con la ruta %UserProfile%\.wslconfig, fuera de cualquier distribución Linux. Podés crearlo con Win + R y notepad %UserProfile%\.wslconfig.
¿Por qué vmmemWSL sigue usando RAM después de cerrar Docker?
Porque la VM de WSL2 conserva la page cache de Linux y no se la devuelve a Windows al terminar el trabajo. Cerrar contenedores no apaga la VM; hace falta un tope en .wslconfig o un wsl --shutdown.
¿Qué valor de memory conviene poner en .wslconfig?
Para 32 GB de RAM física, la regla práctica de dev.to es 8 GB o 12 GB con 4 GB de swap; para 16 GB, entre 4 GB y 6 GB. No es una recomendación oficial: ajustalo según lo que consuman tus builds.
¿Cómo achico el archivo ext4.vhdx de WSL2 y Docker?
Limpiá Docker con docker builder prune -a -f, ejecutá wsl --shutdown y compactá el disco en diskpart con attach vdisk readonly y compact vdisk. Verificá antes la ruta real del archivo y hacé un backup.
Conclusión
El problema no es un bug sino un default generoso: WSL2 puede quedarse con la mitad de tu RAM y no soltarla. Poné memory, processors y swap en [wsl2], aplicá con wsl --shutdown y confirmá con free -h. Tratá autoMemoryReclaim como un complemento opcional, sin repetir la clave, y usá drop_caches solo de manera ocasional. Para el disco, limpiá con cuidado (sin –volumes a ciegas) y compactá el VHDX con diskpart.






