2014-11-06 89 views
0

我发誓我知道这个答案,但我忘了。加载大量的图像导致内存不足

我有这个功能。它加载位图并绘制它们。它可以快速连续调用。大约300左右的位图后,应用程序崩溃,出现System.OutOfMemoryException。

请告诉我,我错了又来了:)

private void PaintPicture() 
    { 
     string FullPath = Global.RunttimePath + EditType.FilePath; 

     if (File.Exists(FullPath)) 
     { 
      Image i = Image.FromFile(FullPath); 
      //DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here 
      i.Dispose(); 
      //GC.Collect(); //I know I know... I should never call GC. So disabled it :) 
     } 
     else 
     { 
      //DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true); 
     } 
    } 
+1

在你的示例代码中,你没有做错任何事情,要么你的问题的来源是其他地方,这段代码只是“St原料打破了骆驼回来“或问题是在你删除的代码发布你的问题在这里。 – 2014-11-06 18:26:18

+0

图像是GDI资源,无论如何都不需要GC'd。 – TaW 2014-11-06 18:38:57

回答

3

Image.FromFile的文档,你可以得到一个OutOfMemoryException如果位图处于未知格式。确保您的应用程序可以安全地加载您尝试使用的所有图像,并查看它是否总是在同一图像上崩溃。

如果它总是相同的图像,那么你可以尝试重新保存支持的像素格式的图像(使用Photoshop或Paint.Net或其他免费工具) - 这应该修复破坏应用程序的特定图像。

此外,添加一个异常处理程序在你的绘图逻辑,以确保当它运行到一个不好的形象您的应用程序不会崩溃 - GDI +仅支持的图像格式数量相对较少。

要验证是否你实际上运行内存(也就是说,如果有泄漏),您的应用程序运行时监视内存的使用。如果你看到内存泄漏的迹象,你的问题可能在其他地方。

编辑:

阅读这些问题/解答咨询有关使用Image.FromStream代替FromFile() - 这样做可以避免锁定很长一段时间的文件:

File.Delete failing when Image.FromFile was called prior it, despite making copy of loaded image and destroying original one

out of memory Image.FromFile

+0

噢呃...我知道..我应该检查这个。某种程度上4623图像中的12个被损坏了。由于线程加载器,我正在执行它,其中任何一个都会崩溃。感谢大家的帮助:) – user2888973 2014-11-06 19:03:59

+0

@ user2888973我知道那是怎么回事,过去我遇到过类似的问题。在一个巨大的文件夹中很难看到坏图片。 – xxbbcc 2014-11-06 19:06:19

+0

@ user2888973我添加了一个链接,解释了为什么'FromStream()'比'FromFile()'好。 – xxbbcc 2014-11-06 19:09:23

1

这可能不会解决你的问题,但图像类实现了IDisposable。这意味着你可以将它包装在一个USING语句中,这会使得对象内部的对象超出范围更快/更少的对象继续存在于L2垃圾收集中(它不应该在使用和调用处理中包装事物之间做出区别,但我们通过内存分析发现它实际上是这样)。

if (File.Exists(FullPath)) 
    { 
     using(Image i = Image.FromFile(FullPath)) 
     { 
      DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here 
      //GC.Collect(); //I know I know... I should never call GC. So disabled it :) 
     } 
    } 
    else 
    { 
     //DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true); 
    } 
} 
+0

+1简化我的代码 – user2888973 2014-11-06 19:06:21

相关问题