使用内存流和图像从数据库中读取图片经常因内存不足而崩溃

Reading pictures from DB using memorystreams and images often crashes with Out of Memory

我正在尝试弄清楚以下代码是否存在严重错误。它从数据库中读取二进制文件,将其存储为图片并与 Animal 记录的对象关联。

对于每一行(一只动物的记录):

byte[] ba = (byte[])x.ItemArray[1]; //reading binary from a DB row
using (MemoryStream m=new MemoryStream(ba))
 {
    Image i = Image.FromStream(m);  //exception thrown occassionally
    c.Photo = i;
    listOfAnimals.Add(c);
 }

首先,加载了 18 张图片(JPG 文件总共有 105 Mb),运行 应用程序使用了 2 GB 的内存。没有加载图片,它只有 500 Mb。 通常在标记点引发异常,其来源是系统绘图。

谁能帮我优化代码或者告诉我问题出在哪里?我一定是用错了函数...

检查documentation,内存不足异常的一个可能原因是流不是有效图像。如果是这种情况,对于给定的图像,它应该可靠地失败,因此请检查是否有任何特定的源图像导致了这个问题。

另一种可能是您 运行 内存不足。 Jpeg 通常获得 10:1 压缩级别,因此 105Mib 的压缩数据可以使用 +1Gib 的内存。如果可能的话,我建议切换到 x64,我认为今天没有理由不这样做。

也可能存在内存泄漏,调查此问题的最佳方法是使用内存分析器。这可能存在于您代码的几乎任何部分,因此如果不进行分析就很难知道。

您可能还需要关心内存碎片问题。大型数据块存储在大型对象堆中,并且不会自动进行碎片整理。因此,在 运行ning 一段时间后,您可能仍有可用内存,只是不在任何连续块中。同样,切换到 x64 将主要解决这个问题。

另外,正如mjwills 所说,请不要在数据库中存储大文件。我只是花了几个小时来恢复一个巨大的数据库,如果将图像存储为文件,这会快得多。

根据Image.FromStream Method

OutOfMemoryException

The stream does not have a valid image format.

Remarks You must keep the stream open for the lifetime of the Image.

The stream is reset to zero if this method is called successively with the same stream.

有关详细信息,请参阅:Loading an image from a stream without keeping the stream open and

尝试以下操作:

创建一个将byte[]转换为image的方法

ConvertByteArrayToImage

public static Image ConvertByteArrayToImage(byte[] buffer) 
{
    using (MemoryStream ms = new MemoryStream(buffer))
    {
        return Image.FromStream(ms);
    }
}

然后:

byte[] ba = (byte[])x.ItemArray[1]; //reading binary from a DB row
c.Photo = ConvertByteArrayToImage(ba);
listOfAnimals.Add(c);