Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WPF中的内存泄漏_C#_.net_Wpf_Memory Leaks - Fatal编程技术网

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

在处理完所有使用过的对象后,我需要减少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_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();