1

The first line fails with System.OutOfMemoryException with the call Image.FromStream:

using (System.Drawing.Image i = System.Drawing.Image.FromStream(new System.IO.MemoryStream(ucDocument1.UploadedFiles[0].FileBytes))) {
//additional code here
}

The byte array is coming from DevExpress.Web.ASPxUploadControl.ASPxUploadControl object and a test which wrote the the fail cases byte arrays to the database and reread successfully from the database proves the byte arrays are valid. The operation is successful for PNG and JPG files of various sizes, and fails for particular known non-corrupt PNG/JPG files, even those that are smaller in size than the success cases. The files failing repeatedly give System.OutOfMemoryException exception. How can this be resolved?

sammarcow
  • 2,736
  • 2
  • 28
  • 56
  • 1
    Are you getting failures on the same images each time or is it more random? Have you tried handling the `OutOfMemoryException` and calling a [GC.Collect](https://msdn.microsoft.com/en-us/library/xe0c2357%28v=vs.110%29.aspx) and then [GC.WaitForPendingFinalizers](https://msdn.microsoft.com/en-us/library/system.gc.waitforpendingfinalizers(v=vs.110).aspx) and then retrying the operation? I found in working with another application that dealt with multi-page tiff files that sometimes it would fail to save pages due to memory issues but calling a GC.Collect would help it succeed. – pstrjds Feb 23 '15 at 23:42
  • I don't think there is a problem with garbage collection because the error occurs consistently with the same files repeatedly for my test cases. – sammarcow Feb 23 '15 at 23:48
  • Okay, that was part of why I was asking if it was consistent with the same images. If it was random then I would lead towards a memory issue. Have you tried just taking the bytes of the images that are causing the error and loading those directly in a test application where all you do is load the image? – pstrjds Feb 23 '15 at 23:50
  • Without seeing the rest of the code, the file that `fails` - is it the **first image** you are attempting to load during program execution or are you trying to load it after successfully loading others? –  Feb 23 '15 at 23:50
  • These other `JPG` files that are failing, can you load them successfully into say `Windows Paint`; `Paint.NET`; `Photoshop` etc? There are many different codecs in JPG for one. If they fail there then perhaps the codec is not supported? [JPEG 2000 support in C#.NET](http://stackoverflow.com/questions/590471/jpeg-2000-support-in-c-net). Not sure if .NET has been updated since then –  Feb 23 '15 at 23:52
  • @MickyDuncan - I've used Windows Preview to verify that the images within my fail case set are valid. – sammarcow Feb 23 '15 at 23:54
  • @pstrjds either way, a known success case can precede the fail case – sammarcow Feb 23 '15 at 23:55
  • @sammarcow Good. Can you elaborate more on _"and fails for particular known non-corrupt PNG/JPG files"_. What exactly are these files? What makes them different to the ones that pass? –  Feb 23 '15 at 23:56
  • I can't tell what makes them different from ones that pass. For all fail cases the images successfully render within Windows Preview before I select them to upload into the control. I verified the byte array written to and read from the database with no modification results in a secondary successful render by Windows Preview. – sammarcow Feb 24 '15 at 00:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/71541/discussion-between-sammarcow-and-micky-duncan). – sammarcow Feb 24 '15 at 00:08

1 Answers1

0

Assuming that you aren't leaking anything, there seem to be some pathological cases where GC fails to do its job properly. For instance, if you are running the Image.FromStream as part of a parallel query, using AsParallel, we've found in some machine configurations that we could run out of memory.

The solution that pstrjds suggested worked for us,

  try
  {
      return (Bitmap)Image.FromStream(stream);
  }
  catch (OutOfMemoryException)
  {
      // retry only once. If it keeps failing it may be something more serious
      GC.Collect();
      GC.WaitForFullGCComplete();
      GC.WaitForPendingFinalizers();
      GC.Collect();
      return (Bitmap)Image.FromStream(stream);
  }

Hope that helps.

endavid
  • 1,781
  • 17
  • 42