Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.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#位图导致内存泄漏_C#_Image_Memory Leaks_Bitmap_Garbage Collection - Fatal编程技术网

C#位图导致内存泄漏

C#位图导致内存泄漏,c#,image,memory-leaks,bitmap,garbage-collection,C#,Image,Memory Leaks,Bitmap,Garbage Collection,我有一个简单的应用程序,它渲染图像并打印出来。为了便于设计,我使用了定制的控件 现在,我有一个1800 x 2400大小的简单控件(是的,非常大): 以及一个扩展类,它使用它生成图像: public static class PhotoProcessor { private static readonly PhotoControl PhotoForm = new PhotoControl(); // Single instance public static Image Gen

我有一个简单的应用程序,它渲染图像并打印出来。为了便于设计,我使用了定制的
控件

现在,我有一个1800 x 2400大小的简单控件(是的,非常大):

以及一个扩展类,它使用它生成图像:

public static class PhotoProcessor
{
    private static readonly PhotoControl PhotoForm = new PhotoControl(); // Single instance

    public static Image GenerateImage(this Photo photo)
    {
        PhotoForm.SetPhoto(photo); // Apply a photo

        Image result;
        
        using (Bitmap b = new Bitmap(PhotoForm.Width, PhotoForm.Height))
        {
            Rectangle r = new Rectangle(0, 0, b.Width, b.Height);
            PhotoForm.DrawToBitmap(b, r); // Draw control to bitmap

            using (MemoryStream ms = new MemoryStream())
            {
                b.Save(ms, ImageFormat.Png); // Save bitmap as PNG
                result = Image.FromStream(ms); 
            }
        }

        // GC.Collect();
        // GC.WaitForPendingFinalizers();

        return result; // return
    }
现在,我尝试使用以下方法生成30张照片:

myPhoto.GenerateImage().Save(@"Output1.png", ImageFormat.Png);
myPhoto.GenerateImage().Save(@"Output2.png", ImageFormat.Png);
我不存储引用,我只保存一个图像,希望GC在保存到文件后收集这些图像

它将占用大约2GB的内存,最后引发一个异常:

System.Drawing.dll中发生类型为“System.OutOfMemoryException”的未处理异常

其他信息:内存不足

如果我看一下Visual Studio诊断工具,它看起来像:

让我们拍一张快照,看看堆的内容,我们将看到有许多
MemoryStream
s:


是什么导致
MemoryStream
产生内存泄漏?据我所知,
using()
生成
Dispose()
调用,该调用应该会处理它

如果我删除注释并调用
GC.Collect();GC.WaitForPendingFinalizers(),则占用的内存将减少2-3倍,但仍会增加-~200个图像仍会杀死一个应用程序

将图像保存更改为以下内容:

Image img;

img = myPhoto.GenerateImage();
img.Save(@"Output1.png", ImageFormat.Png);
img.Dispose();

img = myPhoto.GenerateImage();
img.Save(@"Output2.png", ImageFormat.Png);
img.Dispose();

将产生与使用
GC.Collect()相同的结果。它还将占用更少的内存,但不能消除内存泄漏。

实现了
IDisposable
,因此必须手动处理。您当前正在从
GenerateImage
返回
图像
,但保存后不进行处理。

是否不需要处理
图像
?你把它还了,却再也没有disposing@Rob我猜不存储对图像的引用会使GC收集它。无论如何,保存后使用
Dispose
并不能解决问题。我已经更新了我的答案。谢谢。你绝对确定这就是产生问题的地方吗
MemoryStream
大小始终相同,但您使用的图像不同(例如
Output1.png
Output2.png
)。可能是其他的
内存流
?@Sinatr我在一个空白项目中重现了这个问题,除了这个
GenerateImage
调用之外,它什么都没有。我猜,它总是有相同的大小,因为图像实际上是相同的-看,我总是从
myPhoto
:)@YeldarKurmangaliyev生成一个图像你能在某个地方主持整个解决方案(复制问题的小方案)吗?如果今晚我有时间的话,我可以仔细看看(其他人也可以)
Image img;

img = myPhoto.GenerateImage();
img.Save(@"Output1.png", ImageFormat.Png);
img.Dispose();

img = myPhoto.GenerateImage();
img.Save(@"Output2.png", ImageFormat.Png);
img.Dispose();