Memory Reclaim in the Windows Subsystem for Linux 2

Craig

October 30th, 2019

We’ve added a new Windows Subsystem for Linux (WSL) feature in Windows Insider Preview Build 19013: Memory Reclamation for WSL 2! Previously, when the memory needs of the WSL2 Virtual Machine (VM) would grow, either from your workflow or by the Linux kernel, the overall memory allocated to the VM would also grow by allocating more memory from the host. But, once the workflow is done, that memory which is no longer needed by the workflow would not get released back to the host. Now with memory reclamation in WSL 2, when the memory in Linux is no longer needed it can be reported back to the host where it will be freed and your WSL 2 VM will shrink in memory size.

You can learn all about this new feature by checking out the quick video below or reading on in this blog post.

Hands on with memory reclamation

When a Linux process releases in-use memory, that memory will then be returned to the Windows host. Let’s break this down with an example.

We’ll run a simple C application which will use a large amount of memory. Here’s the source code:

#include <stdlib.h> #include <stdio.h> int main() { int i = 0; char* buffer = (char*) calloc(3000000000,1); printf("Done allocating

"); scanf("%d",&i); free(buffer); return 0; }

Before we run the app, we are using a small amount of memory in both Windows and Linux. We’re measuring the memory used in Windows by watching the memory use of the ‘Vmmem’ process which is responsible for the virtual machine that powers WSL2. In Linux, we used the free -h command to output the amount of used and cached memory.

Once we run the app, memory use in our Linux distro grows and so does our WSL 2 VM’s memory in Windows.

Then we free the in-use memory, and the ‘vmmem’ process which powers your WSL 2 VM shrinks back down in size, meaning that freed memory is now back on your Windows host, and ready to be used in other applications!

The other half of the story: cached memory

User processes are not the only things that use memory in the Linux VM. The Linux kernel also uses many caches including a page cache, which caches file contents to improve file system performance. Let’s look at a more real-world example to see how this comes into play.

We’ll run a sample container app that starts up some databases and a NodeJS server using docker-compose . You can find the source code here: craigloewen-msft/docker-node-mongo (thank you Github user: bradtraversy for creating the original project!)

After we build the images and run the containers, our memory usage is sitting at 2 GB in Windows, even though our in-use memory in Linux is just at 50MB.

This is because we accessed a lot of different files, and now our page cache is at 1.7GB in size. We do not free the page cache until the Linux kernel frees it. This is a design decision to ensure you experience the performance improvements of the page cache. If you wish to drop the contents manually you can run echo 1 > /proc/sys/vm/drop_caches as the root user to do so. Once that memory is freed, then it will also be returned to Windows and your WSL2 VM will shrink in size. In this example, when I close my terminal Windows running the WSL distro the page cache is freed naturally by the Linux kernel.

How it works

This feature is powered by a Linux kernel patch that allows small contiguous blocks of memory to be returned to the host machine when they are no longer needed in the Linux guest. We updated the Linux kernel in WSL2 to include this patch, and modified Hyper-V to support this page reporting feature. In order to return as much memory to the host as possible, we periodically compact memory to ensure free memory is available in contiguous blocks. This only runs when your CPU is idle. You can see when this happens by looking for the ‘WSL2: Performing memory compaction’ message inside of the output of the dmesg command. If you’re a power user you can configure this behavior by editing values in .wslconfig. Please check the WSL 19013 release notes to see these options. Alternatively if you’d like to run this Linux command manually you can run the command echo 1 > /proc/sys/vm/compact_memory as the root user.

Feedback

If you have any questions, or want to stay up to date with news you can find a list of WSL team members that are active on Twitter here. If you run into any technical problems please file an issue on our Github repo: Microsoft/WSL. We’ll be looking forwards to hearing what you think of the new feature!

Further Resources:

Sample commits in the WSL 2 Linux Kernel to enable page reporting: #1 and #2.