Skip to content

Nothing asserts that sustained concurrent use never triggers a collection #52

Closed

Description

@arnelirobles

Band: small

AllocationTests.cs measures a single thread calling an operation in a loop. That proves one call is free. It does not prove the collector stays out of the way, which is the claim that actually matters to anyone sizing a service, and it is the claim nothing in the repository tests.

I measured it and the result is better than the README says. Same core chain, ServerGarbageCollection enabled, 200,000 operations per thread:

Threads Ops B/op Gen0 Gen1 Gen2 Mops/s
1 200,000 0.05 0 0 0 77.5
4 800,000 0.00 0 0 0 1,069.5
8 1,600,000 0.00 0 0 0 1,378.0

Zero collections at every generation, and no degradation with thread count. That is the strongest evidence this project has and it appears in neither the README nor the test suite.

What should change

One test, in the same file as the allocation gate:

[Fact]
public void SustainedConcurrentUseDoesNotCollect()
{
    Warm();
    GC.Collect(2, GCCollectionMode.Forced, blocking: true, compacting: true);
    var gen0 = GC.CollectionCount(0);

    Parallel.For(0, Environment.ProcessorCount, _ =>
    {
        for (var i = 0; i < PerThread; i++)
            Consume(Result<int>.Success(i).Map(Double).Match(Double, OnError));
    });

    Assert.Equal(gen0, GC.CollectionCount(0));
}

Two things to get right, because both are how a test like this becomes flaky:

  • The test host allocates too. Anything else running in the same process during the parallel section can trigger a gen0 and fail the assertion for no reason. Either run it in its own collection with xUnit parallelisation disabled, or assert on GC.GetTotalAllocatedBytes(precise: true) for the measured region and keep the collection count as a looser check.
  • Server GC is a runtime setting, not a source one. The numbers above are with it enabled. The test project needs <ServerGarbageCollection>true</ServerGarbageCollection> or the thresholds will differ from what CI sees.

Blocked on the allocation budget work landing first, since this belongs in the same file and should share its helpers.

Activity

  1. added this to the v3.0 milestone on Aug 30, 2026
  2. self-assigned this
    on Aug 30, 2026
  3. arnelirobles commented on Sep 29, 2026

    @arnelirobles
    ContributorAuthor

    Shipped in 3.0.0 (PR #60, release v3.0.0). PR #60 had
    no per-issue closing keywords, so this stayed open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions