加载大量图像会导致内存不足

本文关键字:内存不足 图像 加载 | 更新日期: 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);
    }
}