Skip to content

jsikstro/MemoryLimitsWindows

Repository files navigation

Limiting how much memory can be committed on Windows

Virtual Address Space

The go-to way to limit how much memory can be committed on Linux (and other POSIX OSs?) is to limit the virtual address space, in turn limiting how much memory can be reserved. This is likely due to Linux supporting different configurations of overcommitting, which makes it practical to limit how much memory can be committed via the virtual address space instead.

AFAIK there is no way to limit the virtual address space on Windows. The size of the virtual address space is dictated by what hardware you're running on, if you're running a 32-bit application on a 64-bit system, and also depending on the version of Windows. Some sources:

Rule of thumb:

  1. x64: Windows 8.1 and Windows Server 2012 R2 or later: 128 TB
  2. Windows Server 2022 and newer supports up to: 4 PB for hosts that support 5-level paging, 256 TB for hosts that support 4-level paging

VirtualMemory.md is a small summary on what values are returned from GlobalMemoryStatusEx() into MEMORYSTATUSEX.

Job Objects

The way I found to limit how much memory that can be committed for a (group of) process(es) is to use Job Objects. Job Objects is also what native Windows Hyper-V containers use to limit memory for both all containers and specific containers.

See JOBOBJECT_BASIC_LIMIT_INFORMATION and JOBOBJECT_EXTENDED_LIMIT_INFORMATION, which contains the following tunable settings:

ProcessMemoryLimit

If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure specifies the JOB_OBJECT_LIMIT_PROCESS_MEMORY value, this member specifies the limit for the virtual memory that can be committed by a process. Otherwise, this member is ignored.

JobMemoryLimit

If the LimitFlags member of the JOBOBJECT_BASIC_LIMIT_INFORMATION structure specifies the JOB_OBJECT_LIMIT_JOB_MEMORY value, this member specifies the limit for the virtual memory that can be committed for the job. Otherwise, this member is ignored.

Process Governor is a popular tool that utilizes Job Object(s) to limit memory for applications.

JobObjectLimitCreateCheck.cpp shows a small example of creating a Job Object that limits the memory for either a single process or all processes in the job, and assigning the current process to that job. Output from that program:

.\JobObjectCreateCheck.exe
No limit
Job Object assigned to the current process
Has limit: 536870912

Containers on Windows (Hyper-V backend, not WSL/Linux)

Implementing resource controls for Windows containers

The Hyper-V backend for Docker on Windows uses Job Objects to limit memory for containers. This does not affect the WSL backend for Docker on Windows, which runs entirely on Linux. To verify how this works, I did a quick experiment with Docker on Windows using the Hyper-V backend with the following minimal Dockerfile (see JobObjectLimitCheck.cpp):

FROM mcr.microsoft.com/windows/servercore:ltsc2022

WORKDIR /app

COPY JobObjectLimitCheck.exe .

CMD JobObjectLimitCheck.exe
$ docker build -t jolc
...

$ docker run  jolc
No limit

$ docker run -m 512m jolc
Has job limit
Has limit: 536870912

The --memory-reservation flag is not supported on Windows:

$ docker run -m 512m --memory-reservation=256m jolc
docker: Error response from daemon: invalid option: Windows does not support MemoryReservation

About

Short study into memory limits on Windows

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages