【问题标题】:C# out of memory exception in GetThumbnailImage on a server服务器上的 GetThumbnailImage 中的 C# 内存不足异常
【发布时间】:2015-02-16 03:31:39
【问题描述】:

当用户向我们发送图像时,我正在运行以下代码来创建缩略图:

public int AddThumbnail(byte[] originalImage, File parentFile)
    {
        File tnFile = null;
        try
        {
            System.Drawing.Image image;
            using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(originalImage))
            {
                image = System.Drawing.Image.FromStream(memoryStream);
            }
            Log.Write("Original image width of [" + image.Width.ToString() + "] and height of [" + image.Height.ToString() + "]");
            //dimensions need to be changeable
            double factor = (double)m_thumbnailWidth / (double)image.Width;

            int thHeight = (int)(image.Height * factor);
            byte[] tnData = null;
            Log.Write("Thumbnail width of [" + m_thumbnailWidth.ToString() + "] and height of [" + thHeight + "]");
            using (System.Drawing.Image thumbnail = image.GetThumbnailImage(m_thumbnailWidth, thHeight, () => false, IntPtr.Zero))
            {                    
                using (System.IO.MemoryStream tnStream = new System.IO.MemoryStream())
                {
                    thumbnail.Save(tnStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    tnData = new byte[tnStream.Length];
                    tnStream.Position = 0;
                    tnStream.Read(tnData, 0, (int)tnStream.Length);
                }
            }
//there is other code here that is not relevant to the problem

        }
        catch (Exception ex)
        {
            Log.Error(ex);
        }

        return (tnFile == null ? -1 : tnFile.Id);
    }

这在我的机器上运行良好,但是当我在测试服务器上运行它时,我总是在线上出现内存不足异常: 使用 (System.Drawing.Image thumbnail = image.GetThumbnailImage(m_thumbnailWidth, thHeight, () => false, IntPtr.Zero)) 它不是在处理大图像:它试图将 480*640 的图像转换为 96*128 的缩略图。我不知道如何调查/解决这个问题。有没有人有任何建议?它总是会发生,即使在我重新启动 IIS 之后也是如此。我最初确实认为图像可能已损坏,但尺寸是正确的。 谢谢。

【问题讨论】:

  • 您是否只是服务器内存不足?拿出你的性能监视器,跟踪堆大小,GC gens,整体内存消耗。
  • 只是一个疯狂的猜测,也许你的机器是 64 位架构,而服务器是 32 位,这意味着你的机器上有更多可用内存
  • GDI 是 notorious 用于抛出 OOM,即使内存不是问题。 GDI 经常在几乎任何错误条件下返回“未能分配内存”,.NET 库将其转换为 OOM,即使分配因其他原因而失败。 可能这是一个合法的记忆问题,但我看到很多其他人追逐这条白鲸,结果证明是别的东西(例如,编解码器标志的错误设置)。
  • 服务器是 64 位的。我很惊讶操纵一个小图像给我这个问题。我会看看内存消耗等

标签: c# image iis server


【解决方案1】:

非常感谢@vcsjones 为我指明了正确的方向。而不是使用 image.GetThumbnailImage 我调用:

public static Image ResizeImage(Image imgToResize, Size size)
    {
        return (Image)(new Bitmap(imgToResize, size));
    }

现在麻烦的代码行是:

using(Image thumbnail = ResizeImage(image, new Size(m_thumbnailWidth, thHeight)))

我从Resize an Image C# 收到这条线 现在可以了!

【讨论】:

    【解决方案2】:

    在我们的 ASP.Net 服务器中使用 GDI+ 操作时也遇到了类似的问题。您提到您在服务器上运行的代码让我想到,这可能是同一个问题。

    请注意,服务器不支持在 System.Drawing 命名空间中使用类。致命的是,它可能会工作一段时间,然后突然(即使没有更改代码)发生错误。

    我们不得不重写服务器代码的重要部分。

    看评论:

    注意事项

    System.Drawing 命名空间中的类是 不支持在 Windows 或 ASP.NET 服务中使用。尝试 从这些应用程序类型之一中使用这些类可能 产生意想不到的问题,例如服务性能下降 和运行时异常。有关受支持的替代方案,请参阅 Windows 成像组件。

    来源: http://msdn.microsoft.com/de-de/library/system.drawing(v=vs.110).aspx

    【讨论】:

    • 谢谢 Stefan,我会去看看的。
    • 5 年后这仍然相关,我刚刚经历了一场噩梦
    猜你喜欢
    • 2011-01-09
    • 2012-01-23
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    • 2010-11-09
    • 2015-09-28
    • 2016-07-27
    • 2010-09-17
    相关资源
    最近更新 更多