【问题标题】:Reading pictures from DB using memorystreams and images often crashes with Out of Memory使用内存流和图像从数据库读取图片通常会因内存不足而崩溃
【发布时间】:2021-10-04 00:23:15
【问题描述】:

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

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

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。 通常在标记点引发异常,其来源是系统绘图。

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

【问题讨论】:

  • 您的内存已用完!唯一的解决方法是添加更多内存或在内存耗尽时将硬盘用作交换空间。
  • @jdweng 但是 105 Mb 的图片怎么会占用和耗尽 2 Gb 的内存呢?我怀疑它没有被正确清除
  • JPEG 被压缩,因此 JPG 文件的大小!= 所需的内存量。图像可能需要每个像素最多 4 个字节。因此,一个 8MP 图像可能只需要 1 - 5 MB 磁盘空间(取决于压缩级别),但可能需要 24 MB 内存。
  • 基本提示 - 不要将二进制文件存储在数据库中。您可以将它们存储在文件系统上吗?
  • 忘了提一下,不要忘记在不再需要图像时、在加载新图像集之前或关闭Form 时处理掉图像。

标签: c# exception memory drawing


【解决方案1】:

根据Image.FromStream Method

OutOfMemoryException

流没有有效的图像格式。

备注 您必须在图像的生命周期内保持流打开。

如果这个方法被同一个流连续调用,则流被重置为零。

欲了解更多信息,请参阅:Loading an image from a stream without keeping the stream openReturning Image using Image.FromStream

尝试以下方法:

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

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);

【讨论】:

    【解决方案2】:

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

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

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

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

    另外,作为mjwills cmets,请不要在数据库中存储大文件。我只花了几个小时来恢复一个庞大的数据库,如果将图像存储为文件,这会更快。

    【讨论】:

    • @mjwills,对不起!
    猜你喜欢
    • 2022-01-08
    • 2013-04-18
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2018-03-08
    相关资源
    最近更新 更多