加载大量图像会导致内存不足
本文关键字:内存不足 图像 加载 | 更新日期: 2023-09-27 18:29:38
我发誓我知道这个问题的答案,但我忘了。
我有这个功能。它加载位图并绘制它们。它可以被迅速地连续调用。在大约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);
}
}
根据Image.FromFile
的文档,如果位图的格式未知,则可以获得OutOfMemoryException
。确保你的应用程序可以安全地加载你试图使用的所有图像,并查看它是否总是在同一个图像上崩溃。
如果它总是相同的图像,那么你可以尝试以支持的像素格式重新保存图像(使用Photoshop或Paint.Net或其他免费工具)-这应该可以修复破坏你的应用程序的特定图像。
此外,在绘图逻辑周围添加一个异常处理程序,以确保应用程序在遇到坏图像时不会崩溃——GDI+只支持相对较少的图像格式。
要验证内存是否真的用完了(也就是说,是否存在泄漏),请在应用程序运行时监视内存使用情况。如果你看到内存泄漏的迹象,那么你的问题很可能在其他地方。
编辑:
阅读以下问题/答案,了解有关使用Image.FromStream
而不是FromFile()
的建议-这样做可以避免长时间锁定文件:
File.Delete在之前调用Image.FromFile时失败,尽管复制了加载的图像并销毁了原始的一个
内存不足Image.FromFile
这可能不会解决您的问题,但Image类实现了IDisposable。这意味着您可以将其包装在USING语句中,这会导致里面的对象更快/更少地超出作用域,这些对象可以存活到二级垃圾收集中(在使用和调用dispose中包装东西之间应该没有区别,但我们通过内存评测发现它确实做到了)。
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);
}
}