无法处理图像 - 内存不足

Cannot Dispose Image - Out of Memory

起初,我有一张图片 (13-15Mb) 和其他五张从原始图片复制而来的图片。完成我的工作后,我想通过单击 Clear Data 按钮来处理所有图像。

我使用诊断工具来了解内存的工作原理。结果,dispose 方法有时有效,有时无效。即使我调用 disposeGC.Collect() 方法,内存仍然增加导致内存不足异常。不知道为什么这么不稳定

下面是我处理数据的方法:

private void ResetDataPatient()
{
    GC.Collect();
    imgBox.Image.Dispose();
    imgBox.Image = Properties.Resources.defaultpicture;
    if (xrayPic != null)
    {
        xrayPic.Dispose();
    }
    if (rootPic != null)
    {
        rootPic.Dispose();
    }
    if (tmppic != null)
    {
        tmppic.Dispose();
    }
    if (tmppicCheck != null)
    {
        tmppicCheck.Dispose();
    }
    if (originalPic != null)
    {
        originalPic.Dispose();
    }
    if (PatienData != null)
    {
        PatienData.Clear();
        PatienData.Dispose();
        PatienData = null;
    }

    GC.Collect();
}

图像将进入大型对象堆 (LOH)。如果您是 运行 32 位或更低的框架版本,低于 4.5,您可能会受到影响。以下是有关 .net 4.5 更改的更多信息。 LOH improvements in .NET 4.5

也可以尝试运行这个代码尽可能多的收集(MSDN link)

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect(2, GCCollectionMode.Forced, true, true);

您只需要处置从资源(例如从文件)创建的图像。如果副本是使用 clone() 方法创建的,则不需要释放它们。您所需要做的就是通过将变量设置为 null 来清除变量引用。无需手动调用 GC:

private void ResetDataPatient() {
    imgBox.Image.Dispose();
    imgBox.Image = Properties.Resources.defaultpicture;
    if (xrayPic != null)
        xrayPic.Dispose();
    xrayPic = null;
    if (rootPic != null)
        rootPic.Dispose();
    rootPic = null;
    if (tmppic != null)
        tmppic.Dispose();
    tmppic = null;
    if (tmppicCheck != null)
        tmppicCheck.Dispose();
    tmppicCheck = null;
    if (originalPic != null)
        originalPic.Dispose();
    originalPic = null;
    if (PatienData != null) {
        PatienData.Clear();
        PatienData.Dispose();
        PatienData = null;
    }
}

配置后将属性设置为null:

private void ResetDataPatient() {
    imgBox.Image.Dispose();
    imgBox.Image = Properties.Resources.defaultpicture;
    if (xrayPic != null)
    {
        xrayPic.Dispose();
        xrayPic = null;
    }
    if (rootPic != null)
    {
        rootPic.Dispose();
        rootPic = null;
    }
    if (tmppic != null)
    {
        tmppic.Dispose();
        tmppic = null;
    }
    if (tmppicCheck != null)
    {
        tmppicCheck.Dispose();
        tmppicCheck = null;
    }
    if (originalPic != null)
    {
        originalPic.Dispose();
        originalPic = null;
    }
    if (PatienData != null) {
        PatienData.Clear();
        PatienData.Dispose();
        PatienData = null;
    }
}