简体   繁体   中英

Out of Memory Exception when Processing Large Number of Images

Im using the following code to fix the Orientation of Images depending on EXIF Data

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

I process a large batch of Images like this

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

But when processing a large batch of images i get Out of Memory exception at

Bitmap image = new Bitmap(FixImageOrientation(Bitmap.FromFile(filepath)));

Why do i get this.. I dispose this image at the end of the loop i guess.

In your code you create two bitmaps but dispose only one. Change your code:

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

This should solve your problems.

As you can find in this answer https://stackoverflow.com/a/7520919/6439999 the call to dispose does not necessarily free memory. This is the task of the Garbage Collector. I assume, that you are loading the images quite fast into the memory. The problem is, that the Garbage collection is only done every now and then. If you are using a huge amount of memory by creating new objects, the garbage collection might be to slow with releasing the memory again.

You could try calling it directly from within you loop with GC.Collect(). If this is not enough, you can also try the blocking parameter, which will pause your thread until the GC run has completed.

As a different approach you can set you project to compile as x64, this will give your program access to more than 1GB of memory. But with this solution you only push the problem further down the road.

Thomas

OUT OF MEMORY EXCEPTION IN FOR LOOP OF THOUSAND OF RECORD , a possible solution:

  1. use using statement in your Program for restricting scope of data base object

  2. assign null value to the list after use

  3. dispose connection object

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM