[release/7.0] Low memory fixes #76674
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.
Customer Impact
This collection of fixes improves the situation when a managed application is run under low memory containers.
Before this change, GCPerfSim (a simple application that continuously allocates memory and keeps a fixed size of them) is unable to survive 70MB under a 600MB container without running into crashes or OutOfMemory.
With these fixes, it is able to survive 280MB (out of the default 450MB hard limit) consistently without crashes or OutOfMemory.
Depending on the types of allocations (i.e. do we (and how much) we allocate on LOH or POH), segments (i.e. .NET 6) were able to survive 300 - 390MB without crashes or OutOfMemory.
This change gets regions closer to 6 (with segments). We could always do better, but that would be a more risky change that we would rather do in .NET 8 instead.
Testing
Beyond testing with GCPerfSim, we ran 48 hours of ReliabilityFramework stress on Windows/x64/Release with both regions and segments and both passed.
None of these changes should have any performance impact, to validate that, I sampled and ran a dozen microbenchmarks and detected no regression.
Risk
Medium, given the change is touching various areas of code.
The change keeps segment intact, so segment is still our safety net. Most changes would be exercised during regular GCs, but they won't make any difference until the process is actually running low on memory.
We ran a lot of tests (reliability and perf) to minimize the risk, and have selected a subset of PRs to be ported to 7.