Repository navigation
Improve WSL2 guest memory reclaim - #41096
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates WSL2’s guest-side memory reduction logic to reclaim memory more efficiently and safely while the VM is idle, aiming to reduce host working set without hurting short-pause resume performance.
Changes:
- Replaces the user-CPU ring-buffer heuristic with aggregate busy/idle CPU sampling from
/proc/stat. - Adds reclaim and compaction behavior tuned for idle periods, including a 2-minute grace period and RAM-scaled reclaim requests via
memory.reclaim(with fallback todrop_caches). - Improves robustness of
/proc/statand/proc/meminfoparsing to avoid terminating the background thread on malformed input.
b1f6752 to
f4c4747
Compare
Copilot-Session: ccc721ed-5fa2-41b2-a5f9-5a8502cdf364
Copilot-Session: ccc721ed-5fa2-41b2-a5f9-5a8502cdf364
David Bennett (dkbennett)
left a comment
There was a problem hiding this comment.
Looks good, recommend adding unit tests for CpuIdleTracker. It would need to be pulled out of the anonymous namespace but could be unit tested for confidence it is correctly tracking these states as expected.
Blue (OneBlue)
left a comment
There was a problem hiding this comment.
LGTM, minor suggestions
| return false; | ||
| } | ||
|
|
||
| unsigned long long fields[8] = {}; |
There was a problem hiding this comment.
nit: This might be a good candidate for using std::regex (can be done in a followup though)
| } | ||
| else if (!droppedThisIdlePeriod) | ||
| { | ||
| if (WriteToFile("/proc/sys/vm/drop_caches", "1\n") == 0) |
There was a problem hiding this comment.
Should we switch this to 3 while we're at it to drop metadata as well ?
|
Good calls, will address as a follow-up. |
* Address follow-ups from PR #41096 - Parse the /proc/stat cpu line with std::regex instead of a manual strtoull cursor loop, while retaining the O_CLOEXEC bounded read. - Use drop_caches=3 in DropCache mode to also drop reclaimable slab (dentries/inodes), matching the SReclaimable slab counted by GetReclaimableCacheBytes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0e37f3d5-68e7-4973-8c27-bf4329c8fd9b * Restrict /proc/stat field separators to spaces/tabs ECMAScript \s matches newlines, so on a truncated aggregate cpu line the optional irq/softirq/steal groups could consume digits from the next line in the read buffer. Use [ \t] so the match cannot span lines. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0e37f3d5-68e7-4973-8c27-bf4329c8fd9b --------- Co-authored-by: Ben HillisCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0e37f3d5-68e7-4973-8c27-bf4329c8fd9b
What this changes
This replaces the existing memory reduction loop with a shared idle detector and simpler reclaim policy.
Modes
drop_cachesonce for the idle periodGradual uses
memory.reclaimwithswappiness=0, which prevents proactive reclaim from swapping anonymous memory. Ifmemory.reclaimis unavailable, it falls back to DropCache.The default remains DropCache.
Why
The current implementation waits approximately ten minutes before dropping cache and only measures user CPU time. This leaves
vmmemWSLelevated long after real workloads finish and can treat kernel or I/O work as idle.The new policy returns memory sooner while preserving cache during short user pauses.
DropCache results
Measured with two clean 16-way Linux kernel builds, two read-heavy source archive runs, and three warm-cache reuse runs per configuration.
The new DropCache policy reaches the existing eventual footprint roughly seven minutes sooner without affecting the 60-second warm-cache case.
Gradual results
A focused test using the same two-minute grace period showed:
vmmemWSLfell from 3.23 GiB to 1.63 GiB by 150 secondsGradual reaches a lower sustained footprint because it continues reclaiming regrown cache toward the floor. DropCache remains the default for compatibility and Gradual remains available for users who prioritize minimum memory usage.
Validation
cmake --build . --config Debug -- -mmemory.reclaimswappiness=0support on the WSL 6.18 kernelvmmemWSL, guest memory, reclaim, compaction, workload timing, and warm-cache reuse data