9

Linux OS:es will typically allow overcommit of memory. For example a process can allocate 100GB memory, even though the machine only has 8GB physical memory and no swap.

As long as all the allocated memory isn't actually used, the process will work. If the program tries to use it all, the OOM-killer will kill processes to free up memory.

How does this work in Windows? Will Windows refuse to give processes virtual memory unless it can guarantee that this memory can be backed by actual memory (physical RAM or swap)?

6
  • 2
    Historically Windows has never allowed overcommit and as far as I know this has not changed in Windows 10. Overcommit has it's advantages but also some potentially serious problems. It can cause a process that has done nothing wrong and made only modest memory allocations to crash with no possibility of recovery. Windows designers took the more cautions decision of never allowing overcommit.
    – LMiller7
    Mar 31, 2017 at 18:17
  • Thanks! Do you know if this is documented somewhere?
    – avl_sweden
    Apr 1, 2017 at 22:36
  • 2
    The Microsoft publication "Windows Internals" 6th edition, covering up to Windows 7, describes memory management. Overcommit is not supported. The 7th edition, covering Windows 10, I believe is not yet released. But I am sure as big a change as overcommit would have been mentioned somewhere. These books can be tough reading if you do not have the background.
    – LMiller7
    Apr 1, 2017 at 22:59
  • Thanks again! Maybe you could put this as an answer so I can accept it?
    – avl_sweden
    Apr 3, 2017 at 7:53
  • @avl_sweden you can write an answer youself. This will at least allow closing duplicate questions. Jul 7, 2017 at 18:14

3 Answers 3

11

Answering my own question, as no one else has.

It seems to be the case that Windows will NOT overcommit memory. This is actually a big difference compared to Linux.

Windows will allow a program to allocate more (virtual) memory than there is RAM on the machine, but ONLY if there is enough free disk space to be able to back the virtual memory requested by the program by disk if necessary.

4
  • 5
    Yes, exactly. The Windows "commit limit" is simply the RAM size + the current pagefile size. Windows won't let applications + the OS commit more than that. If pagefile expansion is enabled and a commit attempt would take you above the current limit (but less than would be allowed by the limits on pagefile expansion) the pagefile is automatically expanded to allow the request. Jul 21, 2017 at 3:47
  • It still needs an OOM killer though, as mine crashed multiple times the past few weeks due to presumably dynamically assigning all my 10 GB free HDD space to Chrome. Feb 6, 2018 at 15:52
  • 1
    Windows is overcommitting memory for stacks! Oct 1, 2019 at 5:45
  • Oh, that's interesting! Do you have a link or other reference for this information?
    – avl_sweden
    Oct 2, 2019 at 7:15
0

Not sure if this is relevant, but certain applications will have their memory use limited, like Powershell, and throw these errors unless memory allocation settings are changed. Or you run commands through a separate application, like Spyder.

3
  • 1
    I wrote a test-program that did a lot of VirtualAlloc-allocations on one side - with these the memory-usage growed -, and created a lot of threads with 1mb default-reservation - and the System-commit grew only as large as the thread's initial stack-pages. Dec 7, 2019 at 17:35
  • @BonitaMontero Yeah, but did you watch the size of the windows "swap file" on disk? Windows does actually reserve all that memory, even if it doesn't show up as committed, if I recall correctly.
    – avl_sweden
    May 2, 2020 at 8:45
  • The system-commit didn't grow, and thereby the swapfile didn'g grow. May 17, 2020 at 5:31
0

Windows does overommit stacks. You can easily create a number of threads with stack space far beyond RAM + swap. The following C++20 program shows the page attributes of a one MB stack:

#include <Windows.h>
#include <iostream>

using namespace std;

int main( int argc, char **argv )
{
    auto stackThread = []( LPVOID lpvThreadParam ) -> DWORD
    {
        ULONG_PTR stackTop, stackBottom;
        GetCurrentThreadStackLimits( &stackBottom, &stackTop );
        char const
            *pStackTop = (char *)stackTop,
            *pStackBottom = (char *)stackBottom;
        SYSTEM_INFO si;
        GetSystemInfo( &si );
        MEMORY_BASIC_INFORMATION mbi;
        auto query = [&]( char const *p ) -> char const *
        {
            if( VirtualQuery( p, &mbi, sizeof mbi ) != sizeof mbi )
                ExitProcess( EXIT_FAILURE );
            return (char *)mbi.AllocationBase;
        };
        char const *base = query( pStackBottom ), *p;
        do
        {
            cout << mbi.RegionSize / si.dwPageSize << ": ";
            unsigned n = 0;
            auto append = [&]<typename ... T>( T &&... values ) { cout << (", " + !n++); ((cout << values), ...); };
            if( mbi.State != MEM_FREE )
                if( mbi.State == MEM_COMMIT )
                    append( "comitted" );
                else if( mbi.State == MEM_RESERVE )
                    append( "reserved" );
                else
                    append( "S: 0x", hex, mbi.State );
            if( !mbi.Protect )
                append( "unacessible" );
            else if( mbi.Protect & PAGE_GUARD )
                append( "guard page" );
            else if( mbi.Protect == PAGE_READWRITE )
                append( "read-write" );
            else
                append( "P: 0x", hex, mbi.Protect );
            cout << endl;
            p = (char *)mbi.BaseAddress + mbi.RegionSize;
        } while( query( p ) == base && mbi.BaseAddress < pStackTop );
        return 123;
    };
    HANDLE hThread = CreateThread( nullptr, 0x100000, stackThread, nullptr, STACK_SIZE_PARAM_IS_A_RESERVATION, nullptr);
    WaitForSingleObject( hThread, INFINITE );
    CloseHandle( hThread );
    return 0;
}

This are the stack attributes shown on my computer:

251:  reserved, unacessible
2:  comitted, guard page
3:  comitted, read-write

As you can see most of the stack is initially uncommitted.

1
  • That's not overcommit, because it's… not committed.
    – porges
    Dec 6 at 1:54

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .