【发布时间】:2018-12-17 05:15:51
【问题描述】:
我很想知道如何在 c# 应用程序中进行内存管理。
即使我处置对象并使其无效,我的应用程序也不会释放内存。 出于测试目的,我创建了如下所述的示例应用程序。
一个应用程序有两个按钮 1)消耗内存 2) 释放内存
通过单击消耗内存,我将创建 500 个内存流对象并将其添加到列表中。
通过单击释放内存,我将处理所有内存流对象并取消该列表。并收集垃圾。
但是当我启动应用程序时,我的任务管理器会显示 8.6 MB 内存使用情况。当我当时按消耗内存时,任务管理器将显示 679.6 MB 内存使用情况。当我按下释放内存时,任务管理器将显示 680.0 MB 内存使用情况。
如何强制释放内存?
代码
public partial class MainWindow : Window
{
List<System.IO.MemoryStream> MemoryStreamCollection = new List<System.IO.MemoryStream>();
public MainWindow()
{
InitializeComponent();
}
private void ConsumeMemory_Click(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 500; i++)
{
MemoryStreamCollection.Add(new System.IO.MemoryStream(System.IO.File.ReadAllBytes(@"D:\TestPDF.pdf")));
}
MessageBox.Show("Done");
}
private void ReleaseMemory_Click(object sender, RoutedEventArgs e)
{
foreach (System.IO.MemoryStream memoryStream in MemoryStreamCollection)
{
memoryStream.Dispose();
}
MemoryStreamCollection = null;
GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
MessageBox.Show("Done");
}
}
应用程序启动时的屏幕截图
消耗内存按钮点击后的屏幕截图。
释放内存按钮点击后的屏幕截图。
【问题讨论】:
-
您是否需要抓住所有物体一次,然后一次性释放它们?如果没有,您可以尝试查看使用
using块创建它们的行为方式,以便在不再需要它们时自动释放它们。 -
你试过不带可选参数调用 GC.Collect() 吗?
-
通过在
MemoryStreamCollection = null;之前添加MemoryStreamCollection.Clear();将不再发生内存泄漏。我已经用你的示例代码成功地测试了它。但是我不知道为什么当你强行调用 GC 时这个 List 没有被收集。即使使用WaitForPendingFinalizers,它也不会被收集。 -
扩展@bommelding 评论、
MemoryStream.Dispose()或MemoryStream.Close()真的不需要调用。它们导致相同的方法,并且没有任何非托管资源。你可以阅读更多here
标签: c# wpf memory memory-management memory-leaks