1
Vote

System.OutOfMemoryException: Insufficient memory to continue the execution of the program

description

When I use GhostscriptRasterizer.GetPage to get PDF page as image, I got the exception, not happening all the time:
System.OutOfMemoryException: Insufficient memory to continue the execution of the program.

System.Runtime.InteropServices.Marshal.AllocHGlobal(IntPtr cb)
Ghostscript.NET.Viewer.GhostscriptViewerDisplayHandler.Page(IntPtr handle, IntPtr device, Int32 copies, Int32 flush)
Ghostscript.NET.GhostscriptDisplayDeviceHandler.display_page(IntPtr handle, IntPtr device, Int32 copies, Int32 flush)
Ghostscript.NET.Interpreter.GhostscriptInterpreter.Run(String str)
Ghostscript.NET.Viewer.GhostscriptViewerPdfFormatHandler.ShowPage(Int32 pageNumber)
Ghostscript.NET.Viewer.GhostscriptViewer.ShowPage(Int32 pageNumber, Boolean refresh)
Ghostscript.NET.Rasterizer.GhostscriptRasterizer.GetPage(Int32 xDpi, Int32 yDpi, Int32 pageNumber)

Code:
using (var source = new MemoryStream(documentFileContent))
            {
                using (var rasterizer = new Ghostscript.NET.Rasterizer.GhostscriptRasterizer())
                {
                    rasterizer.Open(source, version, true);

                    for (var i = 1; i <= rasterizer.PageCount; i++)
                    {
                        var img = rasterizer.GetPage(desiredDpi, desiredDpi, i);

comments

fudong wrote Oct 28, 2014 at 5:55 PM

This exception typically happens when using desiredDpi = 300. However, it seems fine if the desiredDpi = 96. But we really want it to be 300 DPI due to image quality issue.

fudong wrote Oct 28, 2014 at 6:30 PM

I have tried to use the following block to fix it

try{
        img.Save(tmpFile, ImageFormat.Jpeg);
  }
finally
{
      //CI build sometimes fail due to OutOfMemeoryException. So release memory ASAP
      img.Dispose();
 }
but, I still got the except sometimes , not always got exception.

sjdixon wrote Nov 14, 2014 at 11:15 PM

Hey fudong,

As I understand it, the DPI is just an attribute. Changing it doesn't affect the pixel data in any way, nor would it affect the image itself. If you use a library like ImageMagick, you can change it on the fly like this:
int DefaultDpi = 300;
Bitmap img = (Bitmap) rasterizer.GetPage(desiredDpi, desiredDpi, i);
MagickImage image = new MagickImage(img);
image.ResolutionUnits = Resolution.PixelsPerInch;
image.Density = new MagickGeometry(DefaultDpi, DefaultDpi);
So if this is really an issue with the library, then you can bypass it completely. On the other hand, you may also be running out of memory because you are processing some very large pdfs, in which case you have a different problem altogether.