BenchmarkDotNet icon indicating copy to clipboard operation
BenchmarkDotNet copied to clipboard

BenchmarkDotNet freezes when running multiple benchmark classes on .NET 10 (works fine on .NET 8)

Open RealDotNetDave opened this issue 4 months ago • 5 comments

BenchmarkDotNet freezes when running multiple benchmark classes on .NET 10 (works fine on .NET 8)

Description

After migrating my benchmark test suite to .NET 10, the benchmark run intermittently freezes mid-execution. The exact same suite works fine on .NET 8. This has been happening for months and I haven’t identified the cause.

Observed Behavior

  1. Usually occurs when running multiple benchmark classes, especially ones testing collections.
  2. No exception is thrown — the run just freezes and nothing new is logged.
  3. The .NET host process does not terminate after closing the console window.
    • CPU usage continues to fluctuate.
    • The benchmark output folder can’t be deleted until I kill the process (or reboot).
    • Occasionally, I need a full reboot to clear it.
  4. Running one benchmark class at a time typically succeeds.

Expected Behavior

All benchmark classes should run sequentially and the process should exit normally with a summary, logs, and unlocked files.

Actual Behavior

When multiple benchmark classes run back-to-back, the process sometimes freezes indefinitely with no error output, leaving a lingering .NET host process and locked files.

Suspected Cause

Something may not be released/cleaned up when BenchmarkDotNet starts a new benchmark class, particularly in collection-focused benchmarks.

Reproduction Steps

  1. Configure a BenchmarkDotNet job targeting .NET 10.
  2. Run two or more benchmark classes sequentially in the same process.
  3. Observe that execution sometimes freezes after one class completes.

Configuration Snippet


        var config = DefaultConfig.Instance
            .AddJob(Job.Default.WithRuntime(CoreRuntime.Core10_0))
            .WithSummaryStyle(SummaryStyle.Default.WithTimeUnit(BenchmarkDotNet.Horology.TimeUnit.Nanosecond));

        _ = config.WithOption(ConfigOptions.DisableOptimizationsValidator, true);

        // Running multiple classes back-to-back
        _ = BenchmarkRunner.Run<CollectionCreatingBenchmark>(config);
        _ = BenchmarkRunner.Run<CollectionCreatingLoopBenchmark>(config);

Environment

  • BenchmarkDotNet version: 0.15.2
  • .NET SDK version(s): 10.0.100-preview.7.25380.108
  • .NET runtimes tested:
    • .NET 8 (✅ works fine)
    • .NET 10 (❌ freezes)
  • OS: Windows 10 Pro 19045.6216
  • CPU: Intel(R) Core(TM) i5-10400 CPU @ 2.90GHz 2.90 GHz
  • RAM: 32 GB

Frequency / Scope

  • Frequency: intermittent but frequent under load or when running multiple collection-related classes.
  • Scope: only repros on .NET 10; .NET 8 is stable with identical code.

Workarounds Tried

  • Running benchmarks one class at a time → usually succeeds.
  • No exceptions observed; nothing meaningful added to logs.

Attachments

  • Log from the last frozen run
  • Project files showing configuration

Prior Contact

I spoke with someone on the .NET team; they hadn’t seen this before. Posting here first before escalating.

Questions

  • Has anyone seen this behavior before?
  • Would a minimal repro repo help? I can provide one.
  • Any additional logging/diagnosers you’d like enabled on my side?

Thanks!

Project Setup

	<PropertyGroup>
		<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
		<AnalysisLevel>preview</AnalysisLevel>
		<AssemblyVersion>2021.6.4.33120</AssemblyVersion>
		<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
		<Configurations>Release</Configurations>
		<DebugSymbols>true</DebugSymbols>
		<DebugType>none</DebugType>
		<Description>Benchmarking source for the book.</Description>
		<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
		<FileVersion>2022.6.4.33120</FileVersion>
		<GarbageCollectionAdaptationMode>1</GarbageCollectionAdaptationMode>
		<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
		<ImplicitUsings>enable</ImplicitUsings>
		<IsPublishable>False</IsPublishable>
		<LangVersion>preview</LangVersion>
		<NeutralLanguage>en</NeutralLanguage>
		<Nullable>enable</Nullable>
		<NullableContextOptions>enable</NullableContextOptions>
		<OldToolsVersion>2.0</OldToolsVersion>
		<OutputType>Exe</OutputType>
		<Platforms>AnyCPU</Platforms>
		<PlatformTarget>AnyCPU</PlatformTarget>
		<ServerGarbageCollection>true</ServerGarbageCollection>
		<SignAssembly>False</SignAssembly>
		<StartupObject>dotNetTips.CodePerf.Example.App.Program</StartupObject>
		<TieredPGO>true</TieredPGO>
		<TargetFramework>net10.0</TargetFramework>
		<RunAnalyzersDuringBuild>False</RunAnalyzersDuringBuild>
		<RunAnalyzersDuringLiveAnalysis>False</RunAnalyzersDuringLiveAnalysis>
		<EnableNETAnalyzers>False</EnableNETAnalyzers>
		<GenerateDocumentationFile>False</GenerateDocumentationFile>
		<RunPostBuildEvent>Always</RunPostBuildEvent>
		<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
	</PropertyGroup>

dotNetTips.CodePerf.Example.App.BenchmarkTests.CollectionCreatingLoopBenchmark-20250820-194226.log

RealDotNetDave avatar Aug 21 '25 14:08 RealDotNetDave

The fact that it works in .Net 8 tells me it's a runtime bug, but it would be good to isolate the issue before passing it over to them.

Do you observe the same behavior when using a single call to the benchmark runner? E.g.

BenchmarkRunner.Run
([
	BenchmarkConverter.TypeToBenchmarks(typeof(CollectionCreatingBenchmark), config),
	BenchmarkConverter.TypeToBenchmarks(typeof(CollectionCreatingLoopBenchmark), config)
]);

timcassell avatar Aug 23 '25 08:08 timcassell

Very strange that your log file ends with

WorkloadPilot    1: 16 op, 3165000.00 ns, 197.8125 us/op
WorkloadPilot    2: 

Like the runtime got stuck while writing the log.

timcassell avatar Aug 23 '25 08:08 timcassell

Would a minimal repro repo help? I can provide one.

@RealDotNetDave Is it able to provide reproducible sample code? If it's provided. I'll try to investigate it.

filzrev avatar Aug 25 '25 11:08 filzrev

@RealDotNetDave Is this issue can be reproduced on .NET 10 RTM version?

If it able to provide reproducible sample code. I'll try investigate issue.

filzrev avatar Nov 27 '25 09:11 filzrev

Does it still repro on v0.15.8? @filzrev fixed some process bugs (#2877, #2878).

timcassell avatar Dec 08 '25 09:12 timcassell