dotnet / dotnet/wpf

The ItemsControlItemAutomationPeer leads memory leaks

Open
#10,784 2 comments 9 reactions 0 assignees View on GitHub
Investigate
Dominant language
C#
Stars
7.7k
Forks
1.3k
Avg merge
1d 11h
Merged PRs (30d)
61

Description

### Description

Hello, I encountered a memory leak issue with our components. During my research, I found that the key issue is caused by
`System.Windows.Automation.Peers.ItemsControlItemAutomationPeer`.
It holds a reference to the user control (`ViewA`) via the field `_itemsControlAutomationPeer`.

![Image](https://github.com/user-attachments/assets/b3f48e25-f142-4e32-b421-0474476930fe)

### How it works:
- We use a `ContentControl` and two views — `ViewA` and `ViewB`.
- On a button click, I change `ContentControl.Content` to a new instance of the view.
- In this case, I expect that the previous instance of the view (`ViewA`) should be collected, because it has been unloaded from the visual tree.

And this works **until** I start showing any popups.
At that moment, setting the new `RootVisual` causes the [EnsureAutomation](https://github.com/user-attachments/assets/e1a71978-c4ee-408b-85e9-a87dc5fe7c01) call.
This method forces the creation of the automation tree, and from that moment on, `ItemsControlItemAutomationPeer` holds a reference to `ViewA`.

---

Now, I’m looking for any help, solution, or workaround.
This is just a test sample, but we have a real-world scenario where our customer is suffering from this issue.

### Reproduction Steps

- Run `MemoryLeakTestApp`
- Click `ShowPopup` a couple of times
- Take the first snapshot
- Click `ChangeView`
- Take the second snapshot
- Compare them and find the `ViewA`

[MemoryLeakTestApp.zip](https://github.com/user-attachments/files/19792203/MemoryLeakTestApp.zip)

### Expected behavior

The `ViewA` should be collected by the GC

### Actual behavior

The `ViewA` remains in memory

### Regression?

YES.
Under NET 6, it can't be reproduced, but there is another memory leak here (it is caused by `AutomationPeer. _children`.
I also tried to reproduce it under Framework 4.8, but it works properly without leaks

### Known Workarounds

_No response_

### Impact

_No response_

### Configuration

**WPF NET 9. This issue can be reproduced under NET 8 and higher.**

### Other information

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.