dotnet / dotnet/wpf

Dispatcher retains Window object, never to be released after being closed

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

Description

This seems to be a fairly longstanding issue (see links below) which I've only come across myself recently.

* .NET Core Version: This is a .NET 4.72 project, but dotnet reports: .NET Core SDK Version: 3.1.401
* Windows version: Windows 10 (1809, build 17763.1282)
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Don't know
* Is this bug related specifically to tooling in Visual Studio (e.g. XAML Designer, Code editing, etc...)? No


**Problem description:**

I've noticed that Window objects are not released after being closed, even after GC Collect and WaitForPendingFinalizers is called, so its not just an issue of waiting for GC to occur.

I've reproduced this in a a simple test program (code below).

Details: The text "MainWindow finalizer" is not executed by the time of snapshot 2, which seems unexpected. To investigate, I have taken two memory snapshots using VS diagnostic tools at the points indicated in the code listing.

Here's the VS comparison of the two snapshots:

![image](https://user-images.githubusercontent.com/18285074/91334236-a5280800-e79c-11ea-90ad-8633027e6261.png)

This shows that the MainWindow is still around. But why, if nothing is referencing it? Drilling down (again using the diagnostic tools) it turns out that there is a reference after all:

![image](https://user-images.githubusercontent.com/18285074/91334248-aa855280-e79c-11ea-9129-5fbbba0fe031.png)

In this snapshot there are also other objects referencing the MainWindow, but they all eventually form a cycle back to it, so I do not think they are genuinely "root" objects which are keeping the reference alive. But for the MediaContext / Dispatcher duo this is not the case.

To me, this seems like a memory leak, perhaps a WPF bug. I had expected that once the window was Closed, the WPF subsystem would not have any reason to retain it.

If this is expected behavior... its not clear why that would be; and if so, I haven't been able to figure out what the right procedure is to manually clean up.

This issue has come up in the past, in at least three external posts (the first was my own), one from 7-8 years ago:

- https://stackoverflow.com/questions/63586833/window-object-not-released-after-being-closed-even-after-gc-collect-and-waitfor
- https://stackoverflow.com/questions/14411154/a-wpf-window-doesnt-release-the-memory-after-closed
- https://stackoverflow.com/questions/60692407/wpf-window-wont-release-its-resources-untill-program-terminates

Thanks

---

App.xaml:

```

```
App.xaml.cs:

```
namespace memtest
{
public partial class App : Application
{
private void Application_Startup(object sender, StartupEventArgs e)
{
// *** SNAPSHOT 1 ***

ShutdownMode = System.Windows.ShutdownMode.OnExplicitShutdown;

MainWindow window = new MainWindow();
window.Show();
window.Close();
window = null;

GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

// *** SNAPSHOT 2 ***
}
}
}
```
MainWindow.xaml.cs:

```
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Debug.WriteLine("MainWindow constructor");
}

~MainWindow()
{
// Never reached
Debug.WriteLine("MainWindow finalizer");
}
}
```
MainWindow.XAML is the default created by VS, which contains only an empty grid.

There is no other code in the project.

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.