diff --git a/docs/core/runtime-config/garbage-collector.md b/docs/core/runtime-config/garbage-collector.md
index 99f545feab52f..1fd7afa0f57c5 100644
--- a/docs/core/runtime-config/garbage-collector.md
+++ b/docs/core/runtime-config/garbage-collector.md
@@ -209,125 +209,69 @@ Project file:
```
-## Manage resource usage
-
-Use the following settings to manage the garbage collector's memory and processor usage:
-
-- [Affinitize](#affinitize)
-- [Affinitize mask](#affinitize-mask)
-- [Affinitize ranges](#affinitize-ranges)
-- [CPU groups](#cpu-groups)
-- [Heap count](#heap-count)
-- [Heap hard limit](#heap-hard-limit)
-- [Heap hard limit percent](#heap-hard-limit-percent)
-- [Per-object-heap hard limits](#per-object-heap-hard-limits)
-- [Per-object-heap hard limit percents](#per-object-heap-hard-limit-percents)
-- [Region range](#region-range)
-- [Region size](#region-size)
-- [High memory percent](#high-memory-percent)
-- [Retain VM](#retain-vm)
+## Standalone GC
-For more information about some of these settings, see the [Middle ground between workstation and server GC](https://devblogs.microsoft.com/dotnet/middle-ground-between-server-and-workstation-gc/) blog entry.
+To use a standalone garbage collector instead of the default GC implementation, you can specify either the *[path](#path)* (in .NET 9 and later versions) or the *[name](#name)* of a GC native library.
-### Heap count
+### Path
-- Limits the number of heaps created by the garbage collector.
-- Applies to server garbage collection only.
-- If [GC processor affinity](#affinitize) is enabled, which is the default, the heap count setting affinitizes `n` GC heaps/threads to the first `n` processors. (Use the [affinitize mask](#affinitize-mask) or [affinitize ranges](#affinitize-ranges) settings to specify exactly which processors to affinitize.)
-- If [GC processor affinity](#affinitize) is disabled, this setting limits the number of GC heaps.
-- For more information, see the [GCHeapCount remarks](../../framework/configure-apps/file-schema/runtime/gcheapcount-element.md#remarks).
+- Specifies the full path of a GC native library that the runtime loads in place of the default GC implementation. To be secure, this location should be protected from potentially malicious tampering.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.HeapCount` | *decimal value* | .NET Core 3.0 |
-| **Environment variable** | `COMPlus_GCHeapCount` | *hexadecimal value* | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCHeapCount` | *hexadecimal value* | .NET 6 |
-| **app.config for .NET Framework** | [GCHeapCount](../../framework/configure-apps/file-schema/runtime/gcheapcount-element.md) | *decimal value* | .NET Framework 4.6.2 |
-
-[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-
-#### Examples
+| **runtimeconfig.json** | `System.GC.Path` | *string_path* | .NET 9 |
+| **Environment variable** | `DOTNET_GCPath` | *string_path* | .NET 9 |
-*runtimeconfig.json* file:
+### Name
-```json
-{
- "runtimeOptions": {
- "configProperties": {
- "System.GC.HeapCount": 16
- }
- }
-}
-```
+- Specifies the name of a GC native library that the runtime loads in place of the default GC implementation. The behavior changed in .NET 9 with the introduction of the [Path](#path) config.
-*runtimeconfig.template.json* file:
+ In .NET 8 and previous versions:
-```json
-{
- "configProperties": {
- "System.GC.HeapCount": 16
- }
-}
-```
+ - If only a name of the library is specified, the library must reside in the same directory as the .NET runtime (*coreclr.dll* on Windows, *libcoreclr.so* on Linux, or *libcoreclr.dylib* on OSX).
+ - The value can also be a relative path, for example, if you specify "..\clrgc.dll" on Windows, *clrgc.dll* is loaded from the parent directory of the .NET runtime directory.
-> [!TIP]
-> If you're setting the option in *runtimeconfig.json*, specify a decimal value. If you're setting the option as an environment variable, specify a hexadecimal value. For example, to limit the number of heaps to 16, the values would be 16 for the JSON file and 0x10 or 10 for the environment variable.
+ In .NET 9 and later versions, this value specifies a file name only (paths aren't allowed):
-### Affinitize mask
+ - .NET searches for the name you specify in the directory where the assembly that contains your app's `Main` method resides.
+ - If the file isn't found, the .NET runtime directory is searched.
-- Specifies the exact processors that garbage collector threads should use.
-- If [GC processor affinity](#affinitize) is disabled, this setting is ignored.
-- Applies to server garbage collection only.
-- The value is a bit mask that defines the processors that are available to the process. For example, a decimal value of 1023 (or a hexadecimal value of 0x3FF or 3FF if you're using the environment variable) is 0011 1111 1111 in binary notation. This specifies that the first 10 processors are to be used. To specify the next 10 processors, that is, processors 10-19, specify a decimal value of 1047552 (or a hexadecimal value of 0xFFC00 or FFC00), which is equivalent to a binary value of 1111 1111 1100 0000 0000.
+- This configuration setting is ignored if the [Path](#path) config is specified.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.HeapAffinitizeMask` | *decimal value* | .NET Core 3.0 |
-| **Environment variable** | `COMPlus_GCHeapAffinitizeMask` | *hexadecimal value* | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCHeapAffinitizeMask` | *hexadecimal value* | .NET 6 |
-| **app.config for .NET Framework** | [GCHeapAffinitizeMask](../../framework/configure-apps/file-schema/runtime/gcheapaffinitizemask-element.md) | *decimal value* | .NET Framework 4.6.2 |
-
-[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
+| **runtimeconfig.json** | `System.GC.Name` | *string_name* | .NET 7 |
+| **Environment variable** | `COMPlus_GCName` | *string_name* | .NET Core 2.0 |
+| **Environment variable** | `DOTNET_GCName` | *string_name* | .NET 6 |
-#### Examples
+## LOH specific settings
-*runtimeconfig.json* file:
+### Allow very large objects
-```json
-{
- "runtimeOptions": {
- "configProperties": {
- "System.GC.HeapAffinitizeMask": 1023
- }
- }
-}
-```
-
-*runtimeconfig.template.json* file:
+- Configures garbage collector support on 64-bit platforms for arrays that are greater than 2 gigabytes (GB) in total size.
+- Default: GC supports arrays greater than 2-GB. This is equivalent to setting the value to `1`.
+- This option may become obsolete in a future version of .NET.
-```json
-{
- "configProperties": {
- "System.GC.HeapAffinitizeMask": 1023
- }
-}
-```
+| | Setting name | Values | Version introduced |
+| - | - | - | - |
+| **runtimeconfig.json** | N/A | N/A | N/A |
+| **Environment variable** | `COMPlus_gcAllowVeryLargeObjects` | `1` - enabled
`0` - disabled | .NET Core 1.0 |
+| **Environment variable** | `DOTNET_gcAllowVeryLargeObjects` | `1` - enabled
`0` - disabled | .NET 6 |
+| **app.config for .NET Framework** | [gcAllowVeryLargeObjects](../../framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element.md) | `1` - enabled
`0` - disabled | .NET Framework 4.5 |
-### Affinitize ranges
+### Large object heap threshold
-- Specifies the list of processors to use for garbage collector threads.
-- This setting is similar to [System.GC.HeapAffinitizeMask](#affinitize-mask), except it allows you to specify more than 64 processors.
-- For Windows operating systems, prefix the processor number or range with the corresponding [CPU group](/windows/win32/procthread/processor-groups), for example, "0:1-10,0:12,1:50-52,1:7". If you don't actually have more than 1 CPU group, you can't use this setting. You must use the [Affinitize mask](#affinitize-mask) setting. And the numbers you specify are within that group, which means it cannot be >= 64.
-- For Linux operating systems, where the [CPU group](/windows/win32/procthread/processor-groups) concept doesn't exist, you can use both this setting and the [Affinitize mask](#affinitize-mask) setting to specify the same ranges. And instead of "0:1-10", specify "1-10" because you don't need to specify a group index.
-- If [GC processor affinity](#affinitize) is disabled, this setting is ignored.
-- Applies to server garbage collection only.
-- For more information, see [Making CPU configuration better for GC on machines with > 64 CPUs](https://devblogs.microsoft.com/dotnet/making-cpu-configuration-better-for-gc-on-machines-with-64-cpus/) on Maoni Stephens' blog.
+- Specifies the threshold size, in bytes, that causes objects to go on the large object heap (LOH).
+- The default threshold is 85,000 bytes.
+- The value you specify must be larger than the default threshold.
+- The value might be capped by the runtime to the maximum possible size for the current configuration. You can inspect the value in use at run time through the API.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.HeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET Core 3.0 |
-| **Environment variable** | `COMPlus_GCHeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCHeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET 6 |
+| **runtimeconfig.json** | `System.GC.LOHThreshold` | *decimal value* | .NET Core 3.0 |
+| **Environment variable** | `COMPlus_GCLOHThreshold` | *hexadecimal value* | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCLOHThreshold` | *hexadecimal value* | .NET 6 |
+| **app.config for .NET Framework** | [GCLOHThreshold](../../framework/configure-apps/file-schema/runtime/gclohthreshold-element.md) | *decimal value* | .NET Framework 4.8 |
[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
@@ -339,7 +283,7 @@ For more information about some of these settings, see the [Middle ground betwee
{
"runtimeOptions": {
"configProperties": {
- "System.GC.HeapAffinitizeRanges": "0:1-10,0:12,1:50-52,1:7"
+ "System.GC.LOHThreshold": 120000
}
}
}
@@ -350,74 +294,28 @@ For more information about some of these settings, see the [Middle ground betwee
```json
{
"configProperties": {
- "System.GC.HeapAffinitizeRanges": "0:1-10,0:12,1:50-52,1:7"
+ "System.GC.LOHThreshold": 120000
}
}
```
-### CPU groups
-
-- Configures whether the garbage collector uses [CPU groups](/windows/win32/procthread/processor-groups) or not.
-
- When a 64-bit Windows computer has multiple CPU groups, that is, there are more than 64 processors, enabling this element extends garbage collection across all CPU groups. The garbage collector uses all cores to create and balance heaps.
-
- > [!NOTE]
- > This is a Windows-only concept. In older Windows versions, Windows limited a process to one CPU group. Thus, GC only used one CPU group unless you used this setting to enable multiple CPU groups. This OS limitation was lifted in Windows 11 and Server 2022. Also, starting in .NET 7, GC by default uses all CPU groups when running on Windows 11 or Server 2022.
-
-- Applies to server garbage collection on 64-bit Windows operating systems only.
-- Default: GC does not extend across CPU groups. This is equivalent to setting the value to `0`.
-- For more information, see [Making CPU configuration better for GC on machines with > 64 CPUs](https://devblogs.microsoft.com/dotnet/making-cpu-configuration-better-for-gc-on-machines-with-64-cpus/) on Maoni Stephens' blog.
-
-| | Setting name | Values | Version introduced |
-| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.CpuGroup` | `false` - disabled
`true` - enabled | .NET 5 |
-| **Environment variable** | `COMPlus_GCCpuGroup` | `0` - disabled
`1` - enabled | .NET Core 1.0 |
-| **Environment variable** | `DOTNET_GCCpuGroup` | `0` - disabled
`1` - enabled | .NET 6 |
-| **app.config for .NET Framework** | [GCCpuGroup](../../framework/configure-apps/file-schema/runtime/gccpugroup-element.md) | `false` - disabled
`true` - enabled | |
-
-[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-
-> [!NOTE]
-> To configure the common language runtime (CLR) to also distribute threads from the thread pool across all CPU groups, enable the [Thread_UseAllCpuGroups element](../../framework/configure-apps/file-schema/runtime/thread-useallcpugroups-element.md) option. For .NET Core apps, you can enable this option by setting the value of the `DOTNET_Thread_UseAllCpuGroups` environment variable to `1`.
-
-### Affinitize
-
-- Specifies whether to *affinitize* garbage collection threads with processors. To affinitize a GC thread means that it can only run on its specific CPU. A heap is created for each GC thread.
-- Applies to server garbage collection only.
-- Default: Affinitize garbage collection threads with processors. This is equivalent to setting the value to `false`.
-
-| | Setting name | Values | Version introduced |
-| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.NoAffinitize` | `false` - affinitize
`true` - don't affinitize | .NET Core 3.0 |
-| **Environment variable** | `COMPlus_GCNoAffinitize` | `0` - affinitize
`1` - don't affinitize | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCNoAffinitize` | `0` - affinitize
`1` - don't affinitize | .NET 6 |
-| **app.config for .NET Framework** | [GCNoAffinitize](../../framework/configure-apps/file-schema/runtime/gcnoaffinitize-element.md) | `false` - affinitize
`true` - don't affinitize | .NET Framework 4.6.2 |
-
-[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
+> [!TIP]
+> If you're setting the option in *runtimeconfig.json*, specify a decimal value. If you're setting the option as an environment variable, specify a hexadecimal value. For example, to set a threshold size of 120,000 bytes, the values would be 120000 for the JSON file and 0x1D4C0 or 1D4C0 for the environment variable.
-#### Examples
+## Manage resource usage for all GC flavors
-*runtimeconfig.json* file:
+The following settings apply to all flavors of the GC:
-```json
-{
- "runtimeOptions": {
- "configProperties": {
- "System.GC.NoAffinitize": true
- }
- }
-}
-```
-
-*runtimeconfig.template.json* file:
-
-```json
-{
- "configProperties": {
- "System.GC.NoAffinitize": true
- }
-}
-```
+- [Heap hard limit](#heap-hard-limit)
+- [Heap hard limit percent](#heap-hard-limit-percent)
+- [Per-object-heap hard limits](#per-object-heap-hard-limits)
+- [Per-object-heap hard limit percents](#per-object-heap-hard-limit-percents)
+- [Large pages](#large-pages)
+- [Region range](#region-range)
+- [Region size](#region-size)
+- [High memory percent](#high-memory-percent)
+- [Retain VM](#retain-vm)
+- [Conserve memory](#conserve-memory)
### Heap hard limit
@@ -564,6 +462,18 @@ These configuration settings don't have specific MSBuild properties. However, yo
> [!TIP]
> If you're setting the option in *runtimeconfig.json*, specify a decimal value. If you're setting the option as an environment variable, specify a hexadecimal value. For example, to limit the heap usage to 30%, the values would be 30 for the JSON file and 0x1E or 1E for the environment variable.
+### Large pages
+
+- Specifies whether large pages should be used when a heap hard limit is set.
+- Default: Don't use large pages when a heap hard limit is set. This is equivalent to setting the value to `0`.
+- This is an experimental setting.
+
+| | Setting name | Values | Version introduced |
+| - | - | - | - |
+| **runtimeconfig.json** | N/A | N/A | N/A |
+| **Environment variable** | `COMPlus_GCLargePages` | `0` - disabled
`1` - enabled | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCLargePages` | `0` - disabled
`1` - enabled | .NET 6 |
+
### Region range
Starting in .NET 7, the GC heap switched its physical representation from segments to regions for 64-bit Windows and Linux. (For more information, see [Maoni Stephens' blog article](https://itnext.io/how-segments-and-regions-differ-in-decommitting-memory-in-the-net-7-gc-68c58465ab5a).) With this change, the GC reserves a range of virtual memory during initialization. Note that this is only reserving memory, not committing (the GC heap size is committed memory). It's merely a range to define the maximum range the GC heap can commit. Most applications don't need to commit nearly this much.
@@ -667,48 +577,67 @@ Project file:
```
-## Large pages
+### Conserve memory
-- Specifies whether large pages should be used when a heap hard limit is set.
-- Default: Don't use large pages when a heap hard limit is set. This is equivalent to setting the value to `0`.
-- This is an experimental setting.
+- Configures the garbage collector to conserve memory at the expense of more frequent garbage collections and possibly longer pause times.
+- Default value is 0 - this implies no change.
+- Besides the default value 0, values between 1 and 9 (inclusive) are valid. The higher the value, the more the garbage collector tries to conserve memory and thus to keep the heap small.
+- If the value is non-zero, the large object heap will be compacted automatically if it has too much fragmentation.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | N/A | N/A | N/A |
-| **Environment variable** | `COMPlus_GCLargePages` | `0` - disabled
`1` - enabled | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCLargePages` | `0` - disabled
`1` - enabled | .NET 6 |
+| **runtimeconfig.json** | `System.GC.ConserveMemory` | `0` - `9` | .NET 6 |
+| **Environment variable** | `COMPlus_GCConserveMemory` | `0` -`9` | .NET Framework 4.8 |
+| **Environment variable** | `DOTNET_GCConserveMemory` | `0` -`9` | .NET 6 |
+| **app.config for .NET Framework** | [GCConserveMemory](../../framework/configure-apps/file-schema/runtime/gcconservememory-element.md) | `0` -`9` | .NET Framework 4.8 |
-## Allow large objects
+[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-- Configures garbage collector support on 64-bit platforms for arrays that are greater than 2 gigabytes (GB) in total size.
-- Default: GC supports arrays greater than 2-GB. This is equivalent to setting the value to `1`.
-- This option may become obsolete in a future version of .NET.
+Example *app.config* file:
-| | Setting name | Values | Version introduced |
-| - | - | - | - |
-| **runtimeconfig.json** | N/A | N/A | N/A |
-| **Environment variable** | `COMPlus_gcAllowVeryLargeObjects` | `1` - enabled
`0` - disabled | .NET Core 1.0 |
-| **Environment variable** | `DOTNET_gcAllowVeryLargeObjects` | `1` - enabled
`0` - disabled | .NET 6 |
-| **app.config for .NET Framework** | [gcAllowVeryLargeObjects](../../framework/configure-apps/file-schema/runtime/gcallowverylargeobjects-element.md) | `1` - enabled
`0` - disabled | .NET Framework 4.5 |
+```xml
-## Large object heap threshold
+
+
+
+
+
+```
-- Specifies the threshold size, in bytes, that causes objects to go on the large object heap (LOH).
-- The default threshold is 85,000 bytes.
-- The value you specify must be larger than the default threshold.
-- The value might be capped by the runtime to the maximum possible size for the current configuration. You can inspect the value in use at run time through the API.
+> [!TIP]
+> Experiment with different numbers to see which value works best for you. Start with a value between 5 and 7.
+
+## Manage resource usage for Server GC
+
+The following settings affect the number of Server GC threads and if/how they are affinitized to cores. They have no effect on Workstation GC.
+
+- [Heap count](#heap-count)
+- [Affinitize](#affinitize)
+- [Affinitize mask](#affinitize-mask)
+- [Affinitize ranges](#affinitize-ranges)
+- [CPU groups](#cpu-groups)
+- [DATAS](#dynamic-adaptation-to-application-sizes-datas)
+
+For more information about the first 3 settings, see the [Middle ground between workstation and server GC](https://devblogs.microsoft.com/dotnet/middle-ground-between-server-and-workstation-gc/) blog entry.
+
+### Heap count
+
+- Limits the number of heaps created by the garbage collector.
+- Applies to server garbage collection only.
+- If [GC processor affinity](#affinitize) is enabled, which is the default, the heap count setting affinitizes `n` GC heaps/threads to the first `n` processors. (Use the [affinitize mask](#affinitize-mask) or [affinitize ranges](#affinitize-ranges) settings to specify exactly which processors to affinitize.)
+- If [GC processor affinity](#affinitize) is disabled, this setting limits the number of GC heaps.
+- For more information, see the [GCHeapCount remarks](../../framework/configure-apps/file-schema/runtime/gcheapcount-element.md#remarks).
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.LOHThreshold` | *decimal value* | .NET Core 3.0 |
-| **Environment variable** | `COMPlus_GCLOHThreshold` | *hexadecimal value* | .NET Core 3.0 |
-| **Environment variable** | `DOTNET_GCLOHThreshold` | *hexadecimal value* | .NET 6 |
-| **app.config for .NET Framework** | [GCLOHThreshold](../../framework/configure-apps/file-schema/runtime/gclohthreshold-element.md) | *decimal value* | .NET Framework 4.8 |
+| **runtimeconfig.json** | `System.GC.HeapCount` | *decimal value* | .NET Core 3.0 |
+| **Environment variable** | `COMPlus_GCHeapCount` | *hexadecimal value* | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCHeapCount` | *hexadecimal value* | .NET 6 |
+| **app.config for .NET Framework** | [GCHeapCount](../../framework/configure-apps/file-schema/runtime/gcheapcount-element.md) | *decimal value* | .NET Framework 4.6.2 |
[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-### Examples
+#### Examples
*runtimeconfig.json* file:
@@ -716,7 +645,7 @@ Project file:
{
"runtimeOptions": {
"configProperties": {
- "System.GC.LOHThreshold": 120000
+ "System.GC.HeapCount": 16
}
}
}
@@ -727,80 +656,163 @@ Project file:
```json
{
"configProperties": {
- "System.GC.LOHThreshold": 120000
+ "System.GC.HeapCount": 16
}
}
```
> [!TIP]
-> If you're setting the option in *runtimeconfig.json*, specify a decimal value. If you're setting the option as an environment variable, specify a hexadecimal value. For example, to set a threshold size of 120,000 bytes, the values would be 120000 for the JSON file and 0x1D4C0 or 1D4C0 for the environment variable.
-
-## Standalone GC
-
-To use a standalone garbage collector instead of the default GC implementation, you can specify either the *[path](#path)* (in .NET 9 and later versions) or the *[name](#name)* of a GC native library.
+> If you're setting the option in *runtimeconfig.json*, specify a decimal value. If you're setting the option as an environment variable, specify a hexadecimal value. For example, to limit the number of heaps to 16, the values would be 16 for the JSON file and 0x10 or 10 for the environment variable.
-### Path
+### Affinitize
-- Specifies the full path of a GC native library that the runtime loads in place of the default GC implementation. To be secure, this location should be protected from potentially malicious tampering.
+- Specifies whether to *affinitize* garbage collection threads with processors. To affinitize a GC thread means that it can only run on its specific CPU. A heap is created for each GC thread.
+- Applies to server garbage collection only.
+- Default: Affinitize garbage collection threads with processors. This is equivalent to setting the value to `false`.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.Path` | *string_path* | .NET 9 |
-| **Environment variable** | `DOTNET_GCPath` | *string_path* | .NET 9 |
+| **runtimeconfig.json** | `System.GC.NoAffinitize` | `false` - affinitize
`true` - don't affinitize | .NET Core 3.0 |
+| **Environment variable** | `COMPlus_GCNoAffinitize` | `0` - affinitize
`1` - don't affinitize | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCNoAffinitize` | `0` - affinitize
`1` - don't affinitize | .NET 6 |
+| **app.config for .NET Framework** | [GCNoAffinitize](../../framework/configure-apps/file-schema/runtime/gcnoaffinitize-element.md) | `false` - affinitize
`true` - don't affinitize | .NET Framework 4.6.2 |
-### Name
+[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-- Specifies the name of a GC native library that the runtime loads in place of the default GC implementation. The behavior changed in .NET 9 with the introduction of the [Path](#path) config.
+#### Examples
- In .NET 8 and previous versions:
+*runtimeconfig.json* file:
- - If only a name of the library is specified, the library must reside in the same directory as the .NET runtime (*coreclr.dll* on Windows, *libcoreclr.so* on Linux, or *libcoreclr.dylib* on OSX).
- - The value can also be a relative path, for example, if you specify "..\clrgc.dll" on Windows, *clrgc.dll* is loaded from the parent directory of the .NET runtime directory.
+```json
+{
+ "runtimeOptions": {
+ "configProperties": {
+ "System.GC.NoAffinitize": true
+ }
+ }
+}
+```
- In .NET 9 and later versions, this value specifies a file name only (paths aren't allowed):
+*runtimeconfig.template.json* file:
- - .NET searches for the name you specify in the directory where the assembly that contains your app's `Main` method resides.
- - If the file isn't found, the .NET runtime directory is searched.
+```json
+{
+ "configProperties": {
+ "System.GC.NoAffinitize": true
+ }
+}
+```
-- This configuration setting is ignored if the [Path](#path) config is specified.
+### Affinitize mask
+
+- Specifies the exact processors that garbage collector threads should use.
+- If [GC processor affinity](#affinitize) is disabled, this setting is ignored.
+- Applies to server garbage collection only.
+- The value is a bit mask that defines the processors that are available to the process. For example, a decimal value of 1023 (or a hexadecimal value of 0x3FF or 3FF if you're using the environment variable) is 0011 1111 1111 in binary notation. This specifies that the first 10 processors are to be used. To specify the next 10 processors, that is, processors 10-19, specify a decimal value of 1047552 (or a hexadecimal value of 0xFFC00 or FFC00), which is equivalent to a binary value of 1111 1111 1100 0000 0000.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.Name` | *string_name* | .NET 7 |
-| **Environment variable** | `COMPlus_GCName` | *string_name* | .NET Core 2.0 |
-| **Environment variable** | `DOTNET_GCName` | *string_name* | .NET 6 |
+| **runtimeconfig.json** | `System.GC.HeapAffinitizeMask` | *decimal value* | .NET Core 3.0 |
+| **Environment variable** | `COMPlus_GCHeapAffinitizeMask` | *hexadecimal value* | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCHeapAffinitizeMask` | *hexadecimal value* | .NET 6 |
+| **app.config for .NET Framework** | [GCHeapAffinitizeMask](../../framework/configure-apps/file-schema/runtime/gcheapaffinitizemask-element.md) | *decimal value* | .NET Framework 4.6.2 |
-## Conserve memory
+[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-- Configures the garbage collector to conserve memory at the expense of more frequent garbage collections and possibly longer pause times.
-- Default value is 0 - this implies no change.
-- Besides the default value 0, values between 1 and 9 (inclusive) are valid. The higher the value, the more the garbage collector tries to conserve memory and thus to keep the heap small.
-- If the value is non-zero, the large object heap will be compacted automatically if it has too much fragmentation.
+#### Examples
+
+*runtimeconfig.json* file:
+
+```json
+{
+ "runtimeOptions": {
+ "configProperties": {
+ "System.GC.HeapAffinitizeMask": 1023
+ }
+ }
+}
+```
+
+*runtimeconfig.template.json* file:
+
+```json
+{
+ "configProperties": {
+ "System.GC.HeapAffinitizeMask": 1023
+ }
+}
+```
+
+### Affinitize ranges
+
+- Specifies the list of processors to use for garbage collector threads.
+- This setting is similar to [System.GC.HeapAffinitizeMask](#affinitize-mask), except it allows you to specify more than 64 processors.
+- For Windows operating systems, prefix the processor number or range with the corresponding [CPU group](/windows/win32/procthread/processor-groups), for example, "0:1-10,0:12,1:50-52,1:7". If you don't actually have more than 1 CPU group, you can't use this setting. You must use the [Affinitize mask](#affinitize-mask) setting. And the numbers you specify are within that group, which means it cannot be >= 64.
+- For Linux operating systems, where the [CPU group](/windows/win32/procthread/processor-groups) concept doesn't exist, you can use both this setting and the [Affinitize mask](#affinitize-mask) setting to specify the same ranges. And instead of "0:1-10", specify "1-10" because you don't need to specify a group index.
+- If [GC processor affinity](#affinitize) is disabled, this setting is ignored.
+- Applies to server garbage collection only.
+- For more information, see [Making CPU configuration better for GC on machines with > 64 CPUs](https://devblogs.microsoft.com/dotnet/making-cpu-configuration-better-for-gc-on-machines-with-64-cpus/) on Maoni Stephens' blog.
| | Setting name | Values | Version introduced |
| - | - | - | - |
-| **runtimeconfig.json** | `System.GC.ConserveMemory` | `0` - `9` | .NET 6 |
-| **Environment variable** | `COMPlus_GCConserveMemory` | `0` -`9` | .NET Framework 4.8 |
-| **Environment variable** | `DOTNET_GCConserveMemory` | `0` -`9` | .NET 6 |
-| **app.config for .NET Framework** | [GCConserveMemory](../../framework/configure-apps/file-schema/runtime/gcconservememory-element.md) | `0` -`9` | .NET Framework 4.8 |
+| **runtimeconfig.json** | `System.GC.HeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET Core 3.0 |
+| **Environment variable** | `COMPlus_GCHeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET Core 3.0 |
+| **Environment variable** | `DOTNET_GCHeapAffinitizeRanges` | Comma-separated list of processor numbers or ranges of processor numbers.
Unix example: "1-10,12,50-52,70"
Windows example: "0:1-10,0:12,1:50-52,1:7" | .NET 6 |
[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
-Example *app.config* file:
+#### Examples
-```xml
+*runtimeconfig.json* file:
-
-
-
-
-
+```json
+{
+ "runtimeOptions": {
+ "configProperties": {
+ "System.GC.HeapAffinitizeRanges": "0:1-10,0:12,1:50-52,1:7"
+ }
+ }
+}
```
-> [!TIP]
-> Experiment with different numbers to see which value works best for you. Start with a value between 5 and 7.
+*runtimeconfig.template.json* file:
+
+```json
+{
+ "configProperties": {
+ "System.GC.HeapAffinitizeRanges": "0:1-10,0:12,1:50-52,1:7"
+ }
+}
+```
+
+### CPU groups
+
+- Configures whether the garbage collector uses [CPU groups](/windows/win32/procthread/processor-groups) or not.
+
+ When a 64-bit Windows computer has multiple CPU groups, that is, there are more than 64 processors, enabling this element extends garbage collection across all CPU groups. The garbage collector uses all cores to create and balance heaps.
+
+ > [!NOTE]
+ > This is a Windows-only concept. In older Windows versions, Windows limited a process to one CPU group. Thus, GC only used one CPU group unless you used this setting to enable multiple CPU groups. This OS limitation was lifted in Windows 11 and Server 2022. Also, starting in .NET 7, GC by default uses all CPU groups when running on Windows 11 or Server 2022.
+
+- Applies to server garbage collection on 64-bit Windows operating systems only.
+- Default: GC does not extend across CPU groups. This is equivalent to setting the value to `0`.
+- For more information, see [Making CPU configuration better for GC on machines with > 64 CPUs](https://devblogs.microsoft.com/dotnet/making-cpu-configuration-better-for-gc-on-machines-with-64-cpus/) on Maoni Stephens' blog.
+
+| | Setting name | Values | Version introduced |
+| - | - | - | - |
+| **runtimeconfig.json** | `System.GC.CpuGroup` | `false` - disabled
`true` - enabled | .NET 5 |
+| **Environment variable** | `COMPlus_GCCpuGroup` | `0` - disabled
`1` - enabled | .NET Core 1.0 |
+| **Environment variable** | `DOTNET_GCCpuGroup` | `0` - disabled
`1` - enabled | .NET 6 |
+| **app.config for .NET Framework** | [GCCpuGroup](../../framework/configure-apps/file-schema/runtime/gccpugroup-element.md) | `false` - disabled
`true` - enabled | |
+
+[!INCLUDE [runtimehostconfigurationoption](includes/runtimehostconfigurationoption.md)]
+
+> [!NOTE]
+> To configure the common language runtime (CLR) to also distribute threads from the thread pool across all CPU groups, enable the [Thread_UseAllCpuGroups element](../../framework/configure-apps/file-schema/runtime/thread-useallcpugroups-element.md) option. For .NET Core apps, you can enable this option by setting the value of the `DOTNET_Thread_UseAllCpuGroups` environment variable to `1`.
+
+### Dynamic adaptation to application sizes (DATAS)
-## Dynamic adaptation to application sizes (DATAS)
+#### Enabling or disabling DATAS
- Configures the garbage collector to use DATAS. DATAS adapts to application memory requirements, meaning the app heap size should be roughly proportional to the long-lived data size.
- Enabled by default starting in .NET 9.