How WSL2 Actually Manages Memory (and Why vmmem Grows)
WSL2's lightweight VM claims memory dynamically as Linux processes need it — but historically gave that memory back to Windows only reluctantly. Here's what's actually happening, and what you control via .wslconfig.
The vmmem (or Vmmemwsl) process visible in Windows Task Manager, sometimes consuming what looks like an alarming amount of RAM, represents WSL2’s entire lightweight virtual machine — understanding how its memory allocation actually works clarifies whether that number is a problem or expected behavior.
Why WSL2 needs a dedicated memory allocation at all
Because WSL2 runs a genuine Linux kernel inside an actual lightweight VM (unlike WSL1’s syscall-translation approach, which needed no separate memory pool at all), that VM needs its own allocated memory, separate from what any individual Linux process inside it uses directly — vmmem represents this VM-level allocation as a whole, not any single process running inside it.
How dynamic memory allocation is supposed to work
WSL2 is designed to allocate memory from Windows dynamically, growing as Linux-side processes need more, rather than reserving a large fixed amount upfront — in principle, this should mean vmmem shrinks back down once Linux-side memory pressure eases, similar to how memory ballooning works in other virtualization contexts.
Why memory reclaim historically lagged behind expectations
In practice, particularly on earlier WSL2 versions, the VM was often slow to actually release memory back to Windows even after the Linux-side workload that consumed it had finished — Linux’s own page cache behavior (keeping recently-used file data cached in memory speculatively) compounds this, since cached-but-technically-reclaimable memory still shows up as VM memory usage from the Windows side.
What you can directly control via .wslconfig
%UserProfile%\.wslconfig
[wsl2]
memory=4GB
Setting an explicit memory ceiling caps how much RAM the WSL2 VM can ever claim, regardless of Linux-side demand — a hard limit rather than the dynamic, demand-driven allocation than can otherwise grow uncomfortably large under sustained heavy use.
The manual reclaim option
# from within the WSL distro:
echo 1 > /proc/sys/vm/drop_caches
# from Windows, restarting the whole WSL2 VM:
wsl --shutdown
Dropping the Linux-side page cache manually can reclaim some memory without a full restart; a full wsl --shutdown fully tears down and releases the VM’s entire memory allocation, at the cost of ending every running WSL session and process.
Why a memory ceiling is a real tradeoff, not a free improvement
Capping memory via .wslconfig prevents vmmem from growing unboundedly, but a ceiling set too low can cause genuine out-of-memory pressure inside Linux-side workloads that legitimately need more — the right number depends on both your physical RAM and what you’re actually running inside WSL, not a single value that’s correct for everyone.
Why this behavior surprises people coming from WSL1
WSL1 users never encountered this specific concern at all, since WSL1’s syscall-translation architecture had no separate VM memory pool to manage — this is a genuinely new category of resource-management consideration that comes specifically with WSL2’s real-kernel-in-a-VM architecture, not a regression from WSL1, but a different tradeoff traded for WSL2’s much better kernel compatibility.