dotnet / dotnet/maui

[leak-scan] PathGeometry.Figures roots discarded path geometries via shared collection

Open
#38,286 0 comments 0 reactions 0 assignees View on GitHub
agentic-workflows perf/memory-leak 💦
Dominant language
C#
Stars
23.3k
Forks
2k
Avg merge
1d 15h
Merged PRs (30d)
290

Description

`PathGeometry.Figures` strongly subscribes each path geometry to the assigned collection's `CollectionChanged` event. A long-lived/shared `PathFigureCollection` therefore retains discarded `PathGeometry` instances.

**Empirical result**

A standalone `net10.0` xUnit test referencing shipped `Microsoft.Maui.Controls` **10.0.0** created 30 subjects, each holding a 1 MiB payload:

| Scenario | Payloads alive after 7 full GC cycles |
|---|---:|
| Control (never assigns shared collection) | 0/30 |
| Leaky (assigns shared collection) | 30/30 |
| Mitigation (replaces it with a fresh collection) | 0/30 |

Core test setup:

```csharp
var shared = new PathFigureCollection();

// Repeated 30 times; PayloadProperty contains a new 1 MiB byte[] tracked by WeakReference.
var geometry = new PathGeometry();
geometry.SetValue(PayloadProperty, payload);
geometry.Figures = shared;

// Mitigation variant:
geometry.Figures = new PathFigureCollection();
```

Retention path:

`shared PathFigureCollection -> CollectionChanged delegate -> PathGeometry.OnPathFigureCollectionChanged -> discarded PathGeometry -> attached payload`

The current source attaches the strong handler at `src/Controls/src/Core/Shapes/PathGeometry.cs:230-245`; collection replacement detaches it and allows all mitigation payloads to collect.

Expected behavior: assigning shared figures should not permanently root otherwise-unreachable path geometries, or the subscription needs an explicit lifecycle teardown.

This issue was generated by the Daily Memory Leak Hunter workflow using an empirical shipped-package test. No MAUI source build, platform handler, emulator, or native peer was involved.

> Generated by [Daily Memory Leak Hunter](https://github.com/dotnet/maui/actions/runs/34124516166) · gpt56 · 213.6 AIC · ⌖ 12.3 AIC · ⊞ 32.2K · [◷](https://github.com/search?q=repo%3Adotnet%2Fmaui+is%3Aissue+%22gh-aw-workflow-call-id%3A+dotnet%2Fmaui%2Fdaily-leak-hunter%22&type=issues)

Contributor guide

Open the contributing guide

Research direction

Read src/Controls/src/Core/Shapes/PathGeometry.cs around lines 230-245 to inspect the collection-change subscription and replacement behavior. Reproduce the standalone net10.0 xUnit scenario with a shared PathFigureCollection and WeakReference-tracked payloads. Done means discarded PathGeometry instances are no longer retained by the shared collection, or an explicit lifecycle teardown is provided.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.