The compiler tried to allocate more memory than was available and gave up with "virtual memory exhausted". Like an OOM kill, this is a resource ceiling - too much parallelism or a translation unit too heavy for the RAM.
What this error means
A compile aborts with "virtual memory exhausted: Cannot allocate memory". It tends to hit the largest file or the highest -j, and re-running on a bigger machine succeeds unchanged.
On a small runner with little or no swap, a memory-hungry compile exceeds available memory and the allocation fails outright.
High parallelism multiplying memory use
Many concurrent cc1plus processes sum to more than the runner has, so one of them cannot allocate.
How to fix it
Lower parallelism
Fewer concurrent compilers means more memory each.
Terminal
make -j2
# or
ninja -j2 -C build
Add memory or swap
Use a larger runner, or add swap as a stopgap. A self-healing CI platform can retry on a higher-memory runner automatically.
Terminal
# stopgap: add swap on a Linux runner
fallocate -l 4G /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
How to prevent it
Size runners by the build’s peak memory, not just CPU count.
Cap -j to fit memory.
Split or simplify translation units that dominate memory.
Frequently asked questions
What causes ""virtual memory exhausted""?
On a small runner with little or no swap, a memory-hungry compile exceeds available memory and the allocation fails outright.
How do I fix "virtual memory exhausted"?
Fewer concurrent compilers means more memory each.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.