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();