Do you know if this also happens on a native Windows environment?
On native Windows 8 (compiled by Mingw64, with stats taken from task manager); your code consumes 25.6 MB of physical memory. By changing it to "size_t bytes = 1;
" the physical memory consumption changes to 0.2 MB; which implies that the VirtualAlloc()
itself is responsible for about 25.4 MB of physical memory.
Note that some physical memory is needed to keep track of which area/s are reserved; and because you can free/allocate individual pages independently this is likely to be more than just a "start and end for entire area" (and might be a separate marker for every 1 GiB or 2 MiB or 4 KiB piece in the area, to coincide with the structure of tables that the CPU uses for "virtual address to physical address" conversion).
EDIT
Based on comments (repeating tests for different sizes of virtual memory), I slapped together this mess (a loop that doubles the size being allocated and reports the results for each size that worked):
#define __USE_MINGW_ANSI_STDIO 1
#include <windows.h> /* VirtualAlloc() */
#include <psapi.h>
#include <stdio.h> /* getchar() */
#include <stddef.h> /* size_t */
int main(void) {
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
void *address;
size_t size = 1;
hProcess = GetCurrentProcess();
if (NULL == hProcess) {
printf( "OpenProcess() failed\n");
getchar();
return 1;
}
while( (address = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS)) != NULL) {
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) ) {
printf( "Size %zu = Working set size: %u\n", size, pmc.WorkingSetSize );
}
VirtualFree(address, size, MEM_RELEASE);
if(size > SIZE_MAX / 2) {
break;
}
size += size;
}
CloseHandle( hProcess );
getchar();
return 0;
}
On my computer the output is:
Size 1 = Working set size: 1560576
Size 2 = Working set size: 1597440
Size 4 = Working set size: 1597440
Size 8 = Working set size: 1597440
Size 16 = Working set size: 1597440
Size 32 = Working set size: 1597440
Size 64 = Working set size: 1597440
Size 128 = Working set size: 1597440
Size 256 = Working set size: 1597440
Size 512 = Working set size: 1597440
Size 1024 = Working set size: 1597440
Size 2048 = Working set size: 1597440
Size 4096 = Working set size: 1597440
Size 8192 = Working set size: 1597440
Size 16384 = Working set size: 1597440
Size 32768 = Working set size: 1597440
Size 65536 = Working set size: 1597440
Size 131072 = Working set size: 1597440
Size 262144 = Working set size: 1597440
Size 524288 = Working set size: 1597440
Size 1048576 = Working set size: 1597440
Size 2097152 = Working set size: 1597440
Size 4194304 = Working set size: 1597440
Size 8388608 = Working set size: 1597440
Size 16777216 = Working set size: 1597440
Size 33554432 = Working set size: 1597440
Size 67108864 = Working set size: 1597440
Size 134217728 = Working set size: 1597440
Size 268435456 = Working set size: 1597440
Size 536870912 = Working set size: 1597440
Size 1073741824 = Working set size: 1601536
Size 2147483648 = Working set size: 1605632
Size 4294967296 = Working set size: 1613824
Size 8589934592 = Working set size: 1630208
Size 17179869184 = Working set size: 1662976
Size 34359738368 = Working set size: 1728512
Size 68719476736 = Working set size: 1859584
Size 137438953472 = Working set size: 2121728
Size 274877906944 = Working set size: 2646016
Size 549755813888 = Working set size: 3694592
Size 1099511627776 = Working set size: 5791744
Size 2199023255552 = Working set size: 9986048
Size 4398046511104 = Working set size: 18374656
Size 8796093022208 = Working set size: 35151872
Size 17592186044416 = Working set size: 68706304
Size 35184372088832 = Working set size: 135815168