Skip to content

GC HeapHardLimit functionality within .NET Framework 4.8 #863

Description

@mthalman

As part of a recent .NET Framework Container update, we have ported functionality of specifying the heap hard limit similar to what is available on .NET Core.

There is a possible unexpected side-effect due to this new functionality, in that the heap hard limit defaults to 75% of the total available memory, the GC is likely to commit slightly more than what was done previously, hence the process commit size might be larger. This behavior is more pronounced when running multiple processes within the same container.

Theoretically, there should be little to no consequences of much impact, due to how the GC is settings are configured. When the GC detects it's running low on memory, it should collect more aggressively, in order to preserve free space and avoid running out of memory. That said if multiple processes are saturating the memory within the container, increased commit size of each process might lead to a possibility of OOM failures. Since the GC now uses the available memory for the container to determine the minimum heap sizes (and other internal data structures), if the available memory for the container is large you might notice higher commit sizes. This is particularly prominent if the container memory restriction is on the higher side, with multiple managed process launched within it.

Here are some options to affect GC memory settings:

  • COMPlus_GCHeapHardLimit: Hex value which limits the maximum commit size, in bytes, for the GC heap and GC bookkeeping. If you are spawning multiple processes within the container, this could be configured to [available container memory / # of concurrent processes].
  • GCHeapCount: When using Server GC setting, specifies the number of heaps/GC threads to use. The default is to use the number of cores on the machine/container.

NOTE:

If you are using Job Objects to restrict commit size for managed processes, then please ensure that the process is created as suspended, job settings applied to the process and then resumed. Since the GC reads the job settings at startup if the process is not suspended during creation it will lead to incorrect memory settings.

Mitigation

If you are adversely affected by this update, you can remove the update patch from your container image by including the following instruction in your Dockerfile:

RUN dism /Online /Quiet /Remove-Package /PackageName:Package_for_KB9008395~31bf3856ad364e35~amd64~~10.0.4465.1 && %windir%\Microsoft.NET\Framework64\v4.0.30319\ngen update && %windir%\Microsoft.NET\Framework\v4.0.30319\ngen update

This effectively uninstalls this update but preserves all other updates, including the latest security fixes.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions