3
votes

I have done and very easy test, just to understand the wpf how works with memory. I create one project with one window where's a Button. And a second window totally empty. when I press the Button in click open the second window code behind window 1:

/// <summary>
/// Interaction logic for WindowTest1.xaml
/// </summary>
public partial class WindowTest1 : Window
{
    public WindowTest1()
    {
        InitializeComponent();
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var wt2 = new WindowTest2();
        wt2.ShowDialog();
        wt2 = null;
    }
}

xaml window 1:

<Window x:Class="WpfAppXtesting.WindowTest1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfAppXtesting"
    mc:Ignorable="d"
    Title="WindowTest1" Height="450" Width="800">
<Grid>
    <Button Content="Button" HorizontalAlignment="Left" Height="148" Margin="191,138,0,0" VerticalAlignment="Top" Width="267" Click="Button_Click"/>

</Grid>

code behind window2:

 /// <summary>
/// Interaction logic for WindowTest2.xaml
/// </summary>
public partial class WindowTest2 : Window
{
    public WindowTest2()
    {
        InitializeComponent();
    }
}

xaml code window2:

<Window x:Class="WpfAppXtesting.WindowTest2"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfAppXtesting"
    mc:Ignorable="d"
    Title="WindowTest2" Height="450" Width="800">
<Grid>

</Grid>

In the image below I took a screenshot of memory status. the first line I took when start only the first window. the second line when the second window was open. the third line when the second window was close. the last list I took after ten time open and close the second window.

Why the memory don't come back to the first list usage?

enter image description here

1
Yes you have created a test to make garbage that the garbage collector will clean up when it feels like it. you should take a tour around this site docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…TheGeneral
Why the memory don't come back to the first list usage? How did you come up with the expectation that it would come back to the first list usage?mjwills
Because the second window when closed should free its resources occupied with its use.luka

1 Answers

2
votes

First of all you don't call GC.Collect to force an immediate garbage collection after you have closed the second window, so you can't assume that the window has been collected by the time you take the last memory snapshot.

And even if you did call GC.Collect explicitly, you can't assume that the CLR will actually release the occupied memory immediately. Allocating and freeing memory isn't free in terms of performance and as there is a change that the application will request more memory later on, there is no point of releasing the memory segment back to the operating system (OS) immediately.

.NET applications are executed in a managed environment and the CLR is in charge of allocating memory and releasing it back to the OS. How and when it does this is an implementation detail that you can't really control in your application.

The only thing to care about here is that the closed window should be eligible for garbage collection once it has been closed. And it is. Setting the local variable to null once the ShowDialog() method has returned makes no difference.