-
Notifications
You must be signed in to change notification settings - Fork 172
Proposal for docker limits #49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
261698c
Add proposal for docker limits
richlander 7d5852c
Update per design discussions and feedback
richlander b5713ef
Update support-for-docker-limits.md
richlander 3e6282e
Update support-for-docker-limits.md
richlander 226b97d
File rename
richlander File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| # Proposal for .NET Core GC Support for Docker Limits | ||
|
|
||
| .NET Core has support for [control groups](https://en.wikipedia.org/wiki/Cgroups) (cgroups), which is the basis of [Docker limits](https://docs.docker.com/config/containers/resource_constraints/). We found that the algorithm we use to honor cgroups works well for larger memory size limits (for example, >500MB), but that it is not possible to configure a .NET Core application to run indefinitely at lower memory levels. This document proposes an approach to support low memory size limits, <100MB. | ||
|
|
||
| Note: Windows has a concept similar to cgroups called [job objects](https://docs.microsoft.com/windows/desktop/ProcThread/job-objects). .NET Core should honor job objects in the same way as cgroups, as appropriate. This document will focus on cgroups throughout. | ||
|
|
||
| It is critical to provide effective and well defined experiences when .NET Core applications are run within memory-limited cgroups. An application should run indefinitely given a sensible configuration for that application. We considered relying on orchestators to manage failing applications (that can no longer satisfy the configuration of a cgroup), but believe this to be antithetical as a primary solution for building reliable systems. We also expect that there are scenarios where orchestrators will be unavailable or primitive or hardware will be constrainted, and therefore not tolerant of frequently failing applications. As a result, we need a better tuned algorithm for cgroup support to the end of running reliable software within constrained environments. | ||
|
|
||
| See [implementing hard limit for GC heap dotnet/coreclr #22180](https://github.com/dotnet/coreclr/pull/22180). | ||
|
|
||
| ## GC Heap Hard Limit | ||
|
|
||
| The following configuration knobs will be exposed to enable developers to configure their applications: | ||
|
|
||
| * `GCHeapHardLimit` - specifies a hard limit for the GC heap as an absolute value | ||
| * `GCHeapHardLimitPercent` - specifies a hard limit for the GC heap as a percentage of physical memory that the process is allowed to use | ||
|
|
||
| If both are specified, `GCHeapHardLimit` is used. | ||
|
|
||
| The `GCHeapHardLimit` will be calculated using the following formular if it is not specified and the process is running inside a container (or cgroup or job object) with a memory limit specified: | ||
|
|
||
| ```console | ||
| max (20mb, 75% of the memory limit on the container) | ||
| ``` | ||
|
|
||
| The GC will more aggressive perform GCs as the GC heap grows closer to the `GCHeapHardLimit` with the goal of making more memory available so that the application can continue to safely function. The GC will avoid continuously performing full blocking GCs if they are not considered productive. | ||
|
|
||
| The GC will throw an `OutOfMemoryException` when the committed heap size exceeds the `GCHeapHardLimit` memory size after a full compacting GC. | ||
|
|
||
| ## GC Heap Heap Minimum Size | ||
|
|
||
| Using Server GC, there are multiple GC heaps created, up to one per core. This model doesn't scale well when a small memory limit is set on a machine with many cores. | ||
|
|
||
| The minimum _reserved_ segment size per heap: 16mb | ||
|
|
||
| Example: | ||
|
|
||
| * 48 core machine | ||
| * cgroup has a 200MB memory limit | ||
| * cgroup has no CPU/core limit | ||
| * 160MB `GCHeapHardLimit` | ||
| * Server GC will create 10 GC heaps | ||
| * All 48 cores can be used by the application | ||
|
|
||
| Example: | ||
|
|
||
| * 48 core machine | ||
| * cgroup has a 200MB memory limit | ||
| * cgroup has 4 CPU/core limit | ||
| * 160MB `GCHeapHardLimit` | ||
| * Server GC will create 4 GC heaps | ||
| * Only 4 cores can be used by the application | ||
|
|
||
| ## Previous behavior | ||
|
|
||
| Previously, the **maximum GC heap size** matched the cgroup limit. We found that the maximum GC heap size needs to be lower than the cgroup limit in order to account for native component memory requirements and to enable the GC to successfully maintain the managed heap at a sustainable level for a process. | ||
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it mean that the committed memory can be over
GCHeapHardLimitbefore a full compacting GC? My numbers seem to reflect that, but I'd like confirm it's expected.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you using Preview 3 builds and do you have memory limits set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the committed memory used by the GC heap should not be over GCHeapHardLimit if you specified it with one of the configs. the committed memory for the whole process of course can be more than that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it was for the whole process, so that's expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep, expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right ... and that's what the text says, so I think we're good.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The text is confusing. It says that GC will throw
OutOfMemoryExceptionafter a full compacting GC. The GC never throws exceptions right after finishing a GC. The GC throwsOutOfMemoryExceptionexceptions when you try to allocate. I think this should say:The GC will throw an
OutOfMemoryExceptionfor allocations that would cause the committed heap size to exceed theGCHeapHardLimitmemory size, even after a full compacting GC.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm? the GC DOES throw OOM right after a full compacting GC if there's still not enough space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original text made it sound like
GC.Collectmay throw exceptions under certain circumstances. That is not the case. I hope my suggested edit made it clear.The text is using "GC" to mean "garbage collector component" and "act of collecting a garbage" interchangeably. I think it is ok, but it may be sometimes confusing.