Use binding in transform cause memory leak in VS 2022
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET Core Version: 6.0, 4.5
* Windows version: 19044.1826
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes in 4.5.
* Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? **Yes, only in VS2022.**
**Problem description:**
I have a DataTemplate which contains a RotateTransform whose Angle is bound to the model. When I add models to a ItemsControl and then remove them, the memory usage won't fall to initial value and the object count will increase.
**Actual behavior:**
As the sample code below, when the button is clicked, 10,000 models will be added to the window and then be removed. But the memory usage and object count remains. Most of the objects are `WeakReference`, `ConditionalWeakTable`, `ConditionalWeakTable+Container`, `WeakEventManager+ListenerList`.
|Timeline|memory|object count|
|----|----|----|
|initial|61M|34196|
|clicked|133M|155440|
**Expected behavior:**
If I delete the transform or delete the binding, the memory usage and object count will decrease.
|Timeline|memory|object count|
|----|----|----|
|initial|62M|34227|
|clicked|107M|34461|
**Minimal repro:**
**MainWindow.xaml**
```
```
**MainWindow.xaml.cs**
```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
namespace WPFTransformBindingMemoryLeak
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void startB_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 100; i++)
{
List packages = new List();
for (int j = 0; j < 100; j++)
packages.Add(new Shape());
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() =>
{
for (int j = 0; j < 100; j++)
container.Items.Add(packages[j]);
}));
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background, new Action(() =>
{
for (int j = 0; j < 100; j++)
container.Items.Remove(packages[j]);
}));
}
Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle, new Action(() =>
{
GC.Collect();
}));
}
}
public class Shape : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private double angle;
public double Angle
{
get { return angle; }
set
{
angle = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Angle)));
}
}
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.