Skip to content

Fix Avalonia SvgImage reload resource leak#512

Merged
wieslawsoltes merged 3 commits into
masterfrom
fix/issue-433-avalonia-svgimage-leak
May 9, 2026
Merged

Fix Avalonia SvgImage reload resource leak#512
wieslawsoltes merged 3 commits into
masterfrom
fix/issue-433-avalonia-svgimage-leak

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Fix SvgImage Reload Resource Leak

Related Issue

Fixes #433.

Problem

The Avalonia SvgImage control could repeatedly reload the same SVG source when style-related properties changed, even when the effective CSS value had not changed. In the issue repro, the SVG image was placed inside a Button; repeated interaction caused inherited style notifications and reloads of the same icon.

Those reloads replaced the SvgSource's SKSvg, SKPicture, and cached original stream without disposing the previously held native resources. Over time this retained native Skia resources and showed up as memory growth in the Avalonia button scenario.

Changes

Dispose replaced SvgSource resources

  • Added a centralized ReplaceResources path in SvgSource.
  • Ensured previous SKPicture, SKSvg, and cached stream resources are disposed whenever a load or reload replaces them.
  • Preserved the existing render safety behavior by deferring disposal of replaced resources while a render is active.
  • Drained deferred disposals when the last active render exits.
  • Kept resource disposal outside the main lock to avoid expanding the locked section around native disposal work.
  • Preserved the original cached stream position when copying it for reload.

Avoid redundant SvgImage CSS reloads

  • Consolidated CSS and current-CSS reload handling into a shared ReLoadSource helper.
  • Compared requested CSS against the effective loaded source parameters instead of only the init-only SvgSource.Css property.
  • Fell back to init-only SvgSource.Css and SvgSource.Entities when a source has not loaded yet.
  • Reloaded only when the effective CSS actually changes.

Regression tests

  • Added coverage that SvgImage does not reload when the effective CSS is unchanged.
  • Added coverage that a CSS-triggered reload disposes the previous picture.
  • Added coverage that reload during an active render defers previous resource disposal until render completion.
  • Reused reflection helpers for the existing render/dispose deadlock test.

Commit Split

  • f6530baa4 Dispose replaced Avalonia SVG resources

    • src/Svg.Controls.Skia.Avalonia/SvgSource.cs
    • tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgSourceTests.cs
  • 7f2f38a8f Avoid redundant SvgImage CSS reloads

    • src/Svg.Controls.Skia.Avalonia/SvgImage.cs
    • tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgImageTests.cs

Validation

The following checks were run successfully:

dotnet format Svg.Skia.slnx --no-restore --include src/Svg.Controls.Skia.Avalonia/SvgImage.cs src/Svg.Controls.Skia.Avalonia/SvgSource.cs tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgImageTests.cs tests/Svg.Controls.Skia.Avalonia.UnitTests/SvgSourceTests.cs
git diff --check
dotnet test tests/Svg.Controls.Skia.Avalonia.UnitTests/Svg.Controls.Skia.Avalonia.UnitTests.csproj -c Release --no-restore --filter "FullyQualifiedName~SvgImageTests|FullyQualifiedName~SvgSourceTests"
dotnet build Svg.Skia.slnx -c Release --no-restore
dotnet test Svg.Skia.slnx -c Release --no-restore

Focused Avalonia controls tests passed with 15 tests. The full solution test pass completed successfully. The build still reports existing package vulnerability warnings, but no build errors or test failures.

Risk Notes

  • The resource replacement code keeps the existing BeginRender and EndRender synchronization model and only changes when replaced native resources are released.
  • Disposal is intentionally deferred while an active render exists so a render cannot lose the native objects it started with.
  • The CSS reload guard compares effective loaded parameters first, so sources created through markup extensions with SvgParameters.Css are handled correctly.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Avalonia: SvgImage Button Memory Leak

1 participant