Skip to content

fix: Fix headless gui and clock keeping references to emulator and making tests very memory hungry. Added a test to verify this doesnt happen anymore.#2234

Merged
kevinferrare merged 1 commit into
masterfrom
fix/headless_leak
Jun 22, 2026
Merged

fix: Fix headless gui and clock keeping references to emulator and making tests very memory hungry. Added a test to verify this doesnt happen anymore.#2234
kevinferrare merged 1 commit into
masterfrom
fix/headless_leak

Conversation

@kevinferrare

Copy link
Copy Markdown
Contributor

No description provided.

Copilot AI review requested due to automatic review settings June 22, 2026 19:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses memory retention issues in headless/UI-related components and the emulated clock wiring that could keep emulator instances rooted across test runs, leading to high memory usage. It also updates the test suite to rely on xUnit v3’s built-in skip mechanisms and adds an assembly-wide leak guard to prevent regressions.

Changes:

  • Prevent HeadlessGui instances from being rooted via process-lifetime static events by unsubscribing on dispose.
  • Avoid Spice86DependencyInjection being captured by pause/resume event closures by capturing the clock via a local variable instead of the DI instance.
  • Add a suite-wide machine leak tracker/guard and update tests to use Assert.SkipUnless + [Fact] (removing Xunit.SkippableFact usage).

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
tests/Spice86.Tests/Video/VgaRenderer256ColorTestsBase.cs Switches from SkippableFact to xUnit v3 runtime skipping via Assert.SkipUnless.
tests/Spice86.Tests/Video/RendererTestsBase.cs Same: replaces Skip.IfNot/[SkippableFact] with xUnit v3 equivalents.
tests/Spice86.Tests/Spice86Creator.cs Tracks created Machine instances so the assembly-wide leak guard can validate collectability.
tests/Spice86.Tests/Spice86.Tests.csproj Removes Xunit.SkippableFact and uses xunit.v3 (enabling built-in skip + fixtures).
tests/Spice86.Tests/MachineLeakTracker.cs Adds weak-reference tracking of created Machine instances for leak detection.
tests/Spice86.Tests/MachineLeakGuard.cs Adds an assembly fixture that fails the run if tracked machines survive post-dispose GC.
tests/Spice86.Tests/Http/HttpApiGeneratedClientIntegrationTests.cs Moves to IClassFixture and seeds memory values used by assertions.
src/Spice86/ViewModels/Services/HeadlessGui.cs Unsubscribes from static events on dispose to avoid instance rooting/leaks.
src/Spice86/Spice86DependencyInjection.cs Prevents pause handler event closures from capturing the DI instance (reducing retention risk).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


public static int CountSurvivingAfterCollection() {
for (int i = 0; i < 3; i++) {
GC.Collect();
for (int i = 0; i < 3; i++) {
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
…king tests very memory hungry. Added a test to verify this doesnt happen anymore.
@kevinferrare kevinferrare merged commit 4344a59 into master Jun 22, 2026
5 checks passed
@kevinferrare kevinferrare deleted the fix/headless_leak branch June 22, 2026 20:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants