Do not over-commit fiber stacks on Windows #15037
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Whenever a new fiber is spawned on Windows, currently Crystal allocates a fully committed 8 MB range of virtual memory. This commit charge stays until the stack becomes unused and reaped, even when most of the stack goes unused. Thus it is "only" possible to spawn several thousand fibers concurrently before the system runs out of virtual memory, depending on the total size of RAM and page files:
With this PR, for every fresh fiber stack, only the guard pages plus one extra initial page are committed. Spawning 100,000 idle fibers now consumes just around 7.4 GB of virtual memory, instead of 800 GB. Committed pages are also reset after a stack is returned to a pool and before it is retrieved again; this should be reasonably first, as decommitting pages doesn't alter the page contents.
Note that the guard pages reside immediately above the normal committed pages, not at the top of the whole reserved range. This is required for proper stack overflow detection.