runtime: false does not set GC to Client mode on Windows Server 2016

While gathering info for https://github.com/aspnet/AspNetCore/issues/3409, I was getting allocation thresholds for GC collection under various configurations.

On Windows 10, the default GC mode is “Client”. Forcing server via <ServerGarbageCollection>true</ServerGarbageCollection> in the .csproj works (in both net472 and netcoreapp2.1). However, on Windows Server 2106 the default GC mode is “Server”. While a way exists to turn this on, there doesn’t seem to be an equivalent mechanism to turn it off.

Example .csproj:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472;netcoreapp2.1</TargetFramework>
    <ServerGarbageCollection>false</ServerGarbageCollection>
  </PropertyGroup>
</Project>

The lack of any effect on GC was verified at runtime via:

using System;
using System.Runtime;
using static System.Console;

namespace AllocationsTest
{
    public static class Program
    {
        public static void Main(string[] args)
        {
			WriteLine("  GC Mode: " + (GCSettings.IsServerGC ? "Server" : "Client"));
			ReadKey();
		}
	}
}

What does work is an environmental variable approach:

SET COMPlus_gcServer=0

…but it’s my understanding this should work from the .csproj/MSBuild properties as well.

The flip side of this is <ServerGarbageCollection>true</ServerGarbageCollection> to force GC into server mode. The result of this is a section of *.runtimeconfig.json:

{
  "runtimeOptions": {
    "tfm": "netcoreapp2.1",
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "2.1.0"
    },
    "configProperties": { 
      "System.GC.Server": true 
    }
  }
}

When the ServerGarbageCollection MSBuild property is false, the section isn’t generated at all. Letting it generate with true (in a publish) and manually flipping it to false for running that publish also had no effect - still server mode.

In .NET 4.7.2, the old app.config approach also works (but has no effect on netcoreapp2.1, as expected):

<configuration><runtime><gcServer enabled="false" /></runtime></configuration>

Note for anyone looking: this does not happen on a Client OS. It requires a server OS’s default behavior to reproduce.

cc @sebastienros @Maoni0 @adamsitnik @davidfowl

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 21 (21 by maintainers)

Most upvoted comments

.NET Core 2.*

One of the effects is that runtime properties are not populated in .runtimeconfig.json.

I’m sorry - I can’t repro this either now. Not sure how I came to the conclusion yesterday. Right now all I see is the problem with the incremental build.

@Maoni0 yes - I tried a vanilla dotnet new console so that explains it.