Windows is overcommitting stacks

Giganews Newsgroups
Subject: Windows is overcommitting stacks
Posted by:  Bonita Montero (Bonita.Monte…@gmail.com)
Date: Tue, 14 Apr 2020

I've written a little test-program that shows that Windows
has overcommitting, but only for stacks:

#include <Windows.h>
#include <Psapi.h>
#include <iostream>
#include <vector>
#include <thread>
#include <malloc.h>

using namespace std;

#pragma warning(disable: 6255) // alloca might stack overflow
#pragma warning(disable: 6031) // return value ignored

int main()
{
    auto printPrivateUsage = [&]( char const *str )
    {
        PROCESS_MEMORY_COUNTERS_EX pmcx;
        if( !GetProcessMemoryInfo( GetCurrentProcess(),
(PROCESS_MEMORY_COUNTERS *)&pmcx, sizeof pmcx ) )
            return;
        cout << (pmcx.PrivateUsage / 1024 / 1024) << str << endl;
    };
    printPrivateUsage( " MB before 512MB allocated" );
    cout << "press return to allocate 512MB" << endl;
    getchar();
    VirtualAlloc( nullptr, 512 * 1024 * 1024, MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE );
    printPrivateUsage( " MB after memory allocated (pages not touched !)
and before thread created" );
    cout << "press return to create threads" << endl;
    getchar();
    unsigned const N_THREADS  = 1000;
    HANDLE        hSemTouch  = CreateSemaphore( NULL, 0, N_THREADS, NULL ),
                  hSemAllocd  = CreateSemaphore( NULL, 0, N_THREADS, NULL ),
                  hSemGoodbye = CreateSemaphore( NULL, 0, N_THREADS, NULL );
    auto thr = [hSemTouch, hSemAllocd, hSemGoodbye]()
    {
        char a[1];
        WaitForSingleObject( hSemTouch, INFINITE );
        __try
        {
            for( char volatile *p = a; ; *p-- );
        }
        __except( EXCEPTION_EXECUTE_HANDLER )
        {
        }
        ReleaseSemaphore( hSemAllocd, 1, NULL );
        WaitForSingleObject( hSemGoodbye, INFINITE );
    };
    vector<thread> vt;
    for( unsigned t = N_THREADS; t; --t )
        vt.emplace_back( thr );
    printPrivateUsage( " MB after thread created" );
    cout << N_THREADS << " threads created; press return to allocate in
thread-stacks" << endl;
    getchar();
    ReleaseSemaphore( hSemTouch, N_THREADS, NULL );
    for( unsigned t = N_THREADS; t; --t )
        WaitForSingleObject( hSemAllocd, INFINITE );
    printPrivateUsage( " MB after threads have allocated" );
    cout << "stacks read; press return terminate threads" << endl;
    getchar();
    ReleaseSemaphore( hSemGoodbye, N_THREADS, NULL );
    for( thread &t : vt )
        t.join();
}

Replies