Adjust regions range dynamically based on memory limits #71164
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.
This change fixes the working set regression when running the JSON TechEmpower benchmark on Linux under a container. Here is a summary of the performance data:
Segments:
Max Working Set (MB) | 93
Regions before fix:
Max Working Set (MB) | 172
Regions after fix:
Max Working Set (MB) | 95
There is no significant difference between regions after fix and segment on other metrics we measured.
Cause of the regression:
In the GC, we assumed that
GCToOSInterface::VirtualReserve
is essentially free because all it does is that it tells the operating system what virtual address range is not available for other uses within the process. This assumption holds on Windows, but on Linux, the APIs are emulated, and for each page we reserve, we use 1 byte to describe that page so that it can satisfy other needs (e.g. VirtualQuery)On a 64-bit system, the address space is huge, and therefore the GC reserved 256G by default. That translate to 64M of memory used just to track those pages. But we are running under a container of 512MB, we will never ever need those pages.
Solution:
The proper root cause fix is to avoid those tracking bytes, that work is tracked as part of #31721 and is currently out of the scope of .NET 7. In the meantime, there is no need to reserve 256G of memory on a container of 512MB. In this change, I made that reserve limit dynamic, depending on the machine. This will also fix issue #70718 because if you have a large physical memory, our reserve limit would be adjusted accordingly.