Build Governor
The build governor prevents memory exhaustion during parallel C++ builds by monitoring commit charge and throttling compiler processes.
The problem
Section titled “The problem”Each cl.exe process can use 1–4 GB of RAM. With -j16, that’s potentially 64 GB of memory demand. When commit charge hits 100%, Windows becomes unresponsive and builds fail silently.
The error you see is often STATUS_STACK_BUFFER_OVERRUN (0xC0000409), which is misleading — the real cause is std::bad_alloc. This happens because:
- Exception not caught →
std::terminate()called terminate()callsabort()- MSVC’s
/GSsecurity checks interpret this as a buffer overrun
How it works
Section titled “How it works”The governor uses compiler wrappers that intercept cl.exe calls:
- You run
cmake --build . --parallel 16 - Each
cl.exeinvocation hits the wrapper (in PATH) - The wrapper checks if the governor is running — auto-starts it if not
- The wrapper requests tokens based on current commit charge
- The real
cl.exeruns - Tokens are released when compilation finishes
Why commit charge, not free RAM
Section titled “Why commit charge, not free RAM”The governor monitors commit charge because:
- Commit charge = promised memory (even if not yet paged in)
- When the commit limit is reached, allocations fail immediately
- Free RAM is misleading — file cache and standby pages inflate the number
Supported build systems
Section titled “Supported build systems”The wrappers work with all major build systems:
cmake --build . --parallel 16msbuild /m:16ninja -j 8