WPF每次打开和关闭窗口时增加内存

Posted

技术标签:

【中文标题】WPF每次打开和关闭窗口时增加内存【英文标题】:WPF increase memory each time open and close window 【发布时间】:2018-11-26 10:30:09 【问题描述】:

我已经完成了非常简单的测试,只是为了了解 wpf 如何使用内存。 我用一个窗口创建了一个项目,其中有一个Button。 第二个窗口完全是空的。 当我按下Button 点击打开第二个窗口 窗口 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 窗口 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>

window2 后面的代码:

 /// <summary>
/// Interaction logic for WindowTest2.xaml
/// </summary>
public partial class WindowTest2 : Window

    public WindowTest2()
    
        InitializeComponent();
    

xaml 代码窗口2:

<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>

在下图中,我截取了内存状态的屏幕截图。 我只启动第一个窗口时采取的第一行。 第二个窗口打开时的第二行。 第二个窗口关闭时的第三行。 我在打开和关闭第二个窗口十次后得到的最后一个列表。

为什么内存没有回到第一个列表使用量?

【问题讨论】:

是的,您已经创建了一个测试来制造垃圾,垃圾收集器会在需要时清理它。你应该参观一下这个网站docs.microsoft.com/en-us/dotnet/standard/garbage-collection/… Why the memory don't come back to the first list usage? 你是怎么想到它会回到第一个列表使用的? 因为第二个窗口在关闭时应该释放其占用的资源。 【参考方案1】:

首先,在您关闭第二个窗口后,您不会调用GC.Collect 来强制立即进行垃圾回收,因此您不能假设在您拍摄最后一个内存快照时该窗口已被回收。

即使你确实明确地调用了GC.Collect,你也不能假设CLR实际上会立即释放占用的内存。就性能而言,分配和释放内存并不是免费的,并且由于应用程序稍后会请求更多内存的变化,因此没有必要立即将内存段释放回操作系统 (OS)。

.NET 应用程序在托管环境中执行,CLR 负责分配内存并将其释放回操作系统。如何以及何时执行此操作是您无法在应用程序中真正控制的实现细节。

这里唯一需要关心的是,关闭的窗口一旦关闭就应该有资格进行垃圾回收。它是。一旦ShowDialog() 方法返回,将局部变量设置为null 没有任何区别。

【讨论】:

我认为除了 Collect() 之外使用 gc.WaitForPendingFinalizers() 确实提供了一种释放内存的方法——特别是对于像这个问题和/或调试场景这样的情况。 ***.com/a/4257387/3195477

以上是关于WPF每次打开和关闭窗口时增加内存的主要内容,如果未能解决你的问题,请参考以下文章

wpf关闭主窗口询问“退出”的问题

在多个窗口中使用 WPF WebBrowser 控件时发生内存泄漏

C# WPF如何关闭通过父窗口打开的所有子窗口

WPF MVVM从入门到精通7:关闭窗口和打开新窗口

按下 Enter 键时如何关闭 WPF 窗口(对话框)?

如何关闭在不同线程上运行多个窗口的 WPF 应用程序?