Skip to content

Drain finalizers periodically in bestfit-finalize when multithreading is unsupported - #134996

Merged
lewing merged 3 commits into
mainfrom
lewing-fix-bestfit-finalize-browser
Oct 1, 2026
Merged

lewing merged 3 commits into
mainfrom
lewing-fix-bestfit-finalize-browser

Conversation

@lewing

@lewing lewing commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Browser and WASI builds without multithreading have no finalizer thread, so finalizers run from the host event loop (on browser, SystemJS_ScheduleFinalization uses setTimeout(..., 0)). bestfit-finalize's Go() loop allocates requests synchronously and never yields. As a result, no Request finalizer runs, the pinned GCHandles and survivor arrays of dead requests are never released, and the test OOMs at ~3.8 GB.

When RuntimeFeature.IsMultithreadingSupported is false, the test now calls GC.WaitForPendingFinalizers() once every NumRequests iterations. That call drains pending finalizers synchronously. The random sequence, allocation volume, pinning, and pass/fail conditions are unchanged, and no explicit collections are added. Platforms that support multithreading are unaffected.

This is a test workaround. It does not fix the runtime: any synchronous allocation loop without a finalizer thread can starve finalizers the same way.

Validation

  • Desktop: compiled the test standalone and ran it with args 1 200 10000. It passed.
  • Browser/WASI: not run locally. In the issue, @tannergooding reproduced the browser OOM and reported that the same drain workaround passed the failing seed against the CI runtime.

Resolves #132107

Note

This PR description was generated with GitHub Copilot.

lewing and others added 2 commits September 30, 2026 19:52
Browser CoreCLR schedules finalizers on the JS event loop, which the test's
synchronous allocation loop never yields to, so dead requests (and their
pinned handles) are never released and the test OOMs.

Fixes #132107

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 3 pipeline(s).
13 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @anicka-net, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@lewing lewing changed the title Drain finalizers periodically in bestfit-finalize on browser Drain finalizers periodically in bestfit-finalize when multithreading is unsupported Oct 1, 2026
@lewing

lewing commented Oct 1, 2026

Copy link
Copy Markdown
Member Author

/ba-g slow Mac

@lewing
lewing merged commit 9e2b506 into main Oct 1, 2026
86 of 89 checks passed
@lewing
lewing deleted the lewing-fix-bestfit-finalize-browser branch October 1, 2026 11:17
@dotnet-milestone-bot dotnet-milestone-bot Bot added this to the 12.0-preview1 milestone Oct 2, 2026
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test failure: GC/Features/HeapExpansion/bestfit-finalize/bestfit-finalize.cmd

2 participants