C#WPF中的内存泄漏
在处理完所有使用过的对象后,我需要减少c#WPF中的内存泄漏。但是我不能通过使用下面的代码片段完全减少内存消耗 这是我的密码:C#WPF中的内存泄漏,c#,.net,wpf,memory-leaks,C#,.net,Wpf,Memory Leaks,在处理完所有使用过的对象后,我需要减少c#WPF中的内存泄漏。但是我不能通过使用下面的代码片段完全减少内存消耗 这是我的密码: string str; Uri uri; private void Button_Click(object sender, RoutedEventArgs e) // "Load" Button { if(img.Source!=null) Unload(); str = "F://Photos//Parthi//IMG_20141128
string str;
Uri uri;
private void Button_Click(object sender, RoutedEventArgs e) // "Load" Button
{
if(img.Source!=null)
Unload();
str = "F://Photos//Parthi//IMG_20141128_172826244.jpg"; // File Size: 0.643 MB
uri = new Uri(str);
img.Source = new BitmapImage(uri);
}
private void Button_Click_1(object sender, RoutedEventArgs e) //"Unload Button"
{
Unload();
}
private void Unload()
{
Bitmap bmp = GetBitmap(img.Source as BitmapSource);
bmp.Dispose();
bmp = null;
img.Source = null;
str = string.Empty;
uri = null;
}
private Bitmap GetBitmap(BitmapSource source)
{
Bitmap bmp = new Bitmap(source.PixelWidth, source.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
BitmapData data = bmp.LockBits(new System.Drawing.Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
source.CopyPixels(Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride);
bmp.UnlockBits(data);
data = null;
source = null;
return bmp;
}
运行样本后,在任务管理器中检查样本时,产生了以下内存消耗读数
单击“加载”按钮之前:10.0 MB
单击“加载”按钮后:47.8 MB
单击“卸载”按钮后:26.0 MB
卸载后,我需要将内存减少到10.0 MB。所以请帮我解决这个问题
提前感谢。使用.net平台无法像在c/c中一样控制内存++ 垃圾回收器操作非常复杂的策略,而且内存减少到26但减少到10是正常的。 net保留了一个空间来为更快的数据充电,并保证主内存中的可用空间,而不需要连续的操作系统 我注意到的是完全正常的。 这是一个问题,在过去的一个课程中,我个人受到了微软MVP的影响 查看以下内容:
这是:尝试管理变量的使用。您可以这样做:
private void Button_Click(object sender, RoutedEventArgs e)
{
img.Source = new BitmapImage(new Uri(@"F://Photos//Parthi//IMG_20141128_172826244.jpg"));
}
如果整个类不需要'str'和'uri',您可以直接将其添加到对象中。或者,如果您真的需要存储它并重用真正具有巨大大小的数据,您可以将其存储在临时文件的物理文件中,以防止内存泄漏;您可以将其存储在物理存储器上,而不是存储在内存中
希望它能对你的
Unload
方法调用GetBitmap
有所帮助,但是GetBitmap
每次都会返回一个新对象,据我所知,你永远不会真正处理img。Source
正确地首先,不要使用任务管理器查看你的内存使用情况,因为它只显示windows进程分配的内存。有很多更好的工具,甚至是Windows上的性能监视器,都可以让您更好地了解应用程序性能和内存泄漏。您可以通过运行perfmon.exe
来启动它
在这个示例应用程序中,在堆达到大约85MB之前,GC不会攻击集合。我为什么要这样做?它没有太多内存,如果我决定再次使用相同的对象,它可以很好地作为缓存解决方案
所以,我建议看看这个工具。它提供了一个关于正在发生的事情的很好的概述,而且是免费的
其次,调用.Dispose()
释放这些资源并不意味着立即释放内存。您基本上是让它符合垃圾收集的条件,当GC到达它时,它会处理它
WPF应用程序的默认垃圾收集行为是并发的(call
GC.Collect()
在卸载
函数位图
的末尾,它继承了图像
,实现了IDisposable
…为什么不利用这一点并使用使用
?顺便问一下,为什么您有如此严格的要求,不能让WPF和.NET为您管理内存?我可能错了,但是如果你想要这样的微观管理级别,我觉得C或C++可能是更好的选择。你读到什么内存度量?记住,根据你如何测量内存使用量,你可能比你需要的更多的分配,因为垃圾收集器还没有到达。显式调用GC。这几乎总是一个坏主意,因为它会干扰垃圾收集器的自调整算法。任务管理器不会显示应用程序的“真实”实际内存使用情况。如果你真的想知道你的内存使用情况,请使用内存分析器。你可以下载试用版。但我可以向你保证,投资于这样的工具肯定是非常有用的不浪费钱。这会分配等量的内存。只要实例化一个对象,它就会分配内存。不管它是内联的还是非内联的。该变量的作用域是方法。因此,只有在方法结束后才会释放内存(用于在对象为一次性对象时调用dispose。)
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collection();