【问题标题】:Out of Memory Exception when Processing Large Number of Images处理大量图像时出现内存不足异常
【发布时间】:2016-09-02 16:11:40
【问题描述】:

我使用以下代码根据 EXIF 数据修复图像的方向

 Image FixImageOrientation(Image srce)
        {
            const int ExifOrientationId = 0x112;
            // Read orientation tag
            if (!srce.PropertyIdList.Contains(ExifOrientationId)) return srce;
            var prop = srce.GetPropertyItem(ExifOrientationId);
            var orient = BitConverter.ToInt16(prop.Value, 0);
            // Force value to 1
            prop.Value = BitConverter.GetBytes((short)1);
            srce.SetPropertyItem(prop);
          //  MessageBox.Show(orient.ToString());
            // Rotate/flip image according to <orient>
            switch (orient)
            {

                case 1:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;


                case 2:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipX);
                    return srce;

                case 3:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    return srce;

                case 4:
                    srce.RotateFlip(RotateFlipType.Rotate180FlipX);
                    return srce;

                case 5:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipX);
                    return srce;

                case 6:
                    srce.RotateFlip(RotateFlipType.Rotate90FlipNone);
                    return srce;

                case 7:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipX);
                    return srce;

                case 8:
                    srce.RotateFlip(RotateFlipType.Rotate270FlipNone);
                    return srce;

                default:
                    srce.RotateFlip(RotateFlipType.RotateNoneFlipNone);
                    return srce;
            }
        }

我处理了大量这样的图像

for (x= 0; x<list.Count; x++)
{
filepath= list.ElementAt(x);
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));
//Do long processing and at the end i do image.dispose();
image.dispose();
}

但是在处理大量图像时,我在

处遇到内存不足异常
Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));

为什么我会得到这个。我猜我在循环结束时处理了这个图像。

【问题讨论】:

  • 您正在创建 2 个图像,并且只处理一个 Bitmap.FromFile(filepath)new Bitmap(
  • Ghetto 方式,在运行程序时打开 Windows 任务管理。如果你看到内存快速上升,那么你在某处有内存泄漏,

标签: c# .net bitmap out-of-memory gdi+


【解决方案1】:

在您的代码中,您创建了两个位图,但只处理了一个。 更改您的代码:

using(var source = Bitmap.FromFile(filepath)) {
    using(var image = new Bitmap(FixImageOrientation(source))) {
       // ... do long processing
    }
}

这应该可以解决您的问题。

【讨论】:

  • 谢谢.. 因为图像是一个全局对象.. 我想我可以简单地使用using(var source = Bitmap.FromFile(filepath)) { Bitmap image = new Bitmap(FixImageOrientation(source)); } 并使用image.dispose(); 处理掉image .. 这行得通吗?
  • @techno 抱歉,我不明白你的意思。您必须处理两个位图。
  • 我的意思是..我在代码中分配image对象。如果我使用using声明image我不能这样做所以我只使用这个using(var source = Bitmap.FromFile(filepath)) {并创建@987654329 @ 来自source 并手动处理掉image 对象...而不是使用第二个using statment。
  • 我不能因为......你不能为使用using语句创建的对象赋值。
  • 为什么需要重新分配image
【解决方案2】:

您可以在此答案https://stackoverflow.com/a/7520919/6439999 中找到对 dispose 的调用不一定会释放内存。这是垃圾收集器的任务。我假设您将图像加载到内存中的速度非常快。问题是,垃圾收集只是不时进行。如果您通过创建新对象来使用大量内存,则垃圾收集可能会因再次释放内存而变慢。

您可以尝试使用 GC.Collect() 从循环中直接调用它。 如果这还不够,你也可以试试blocking参数,它会暂停你的线程,直到GC运行完成。

作为另一种方法,您可以将项目设置为编译为 x64,这将使您的程序可以访问超过 1GB 的内存。但是使用此解决方案只会将问题推得更远。

托马斯

【讨论】:

    【解决方案3】:

    在 FOR LOOP OF THOUSAND OF RECORD 中出现内存不足异常,一种可能的解决方案:

    1. 在程序中使用 using 语句来限制数据库对象的范围

    2. 使用后将空值赋给列表

    3. 释放连接对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-16
      • 2011-04-13
      • 1970-01-01
      • 2011-06-18
      • 2015-02-19
      相关资源
      最近更新 更多