Search code examples
c#out-of-memorypdfclown

PDFClown System.OutOfMemoryException while populating large file


I am generating a large Report pdf file using PDFClown using data from a database.

The process takes a very long time and eventually runs out of memory when the number of pages nears the 150 mark taking up more than 1.5GB of ram and with the error:

A first chance exception of type 'System.OutOfMemoryException' occurred in PDFClown.dll

Since I will need to regularly generate reports of over 1500 pages this is a major problem.

Is there anything I can do to:

  1. Not run out of memory (Necessary)
  2. Speed up the file creation (Ideally)

Please note: the reports generated (with smaller data sets) are accurate, although the file size is rather large.

Here is a sample of my code:

protected void PopulateReport()
{
    foreach (Page page in _lstPages)
    {
        if (page != _Titlepage)
        {
            PrimitiveComposer composer = new PrimitiveComposer(page);
            BlockComposer blockComposer = new BlockComposer(composer);

            DataRow drInspection;
            if (_mapPage1Rows.TryGetValue(page, out dataRow))
            {
                GeneratePage1(page, composer, blockComposer, dataRow);
            }
            else if (_mapPage2Rows.TryGetValue(page, out dataRow))
            {
                GeneratePage2(page, composer, blockComposer, dataRow);
            }
        }
    }
}
protected void GeneratePage1()
{
    composer.BeginLocalState();
    composer.SetFont(ReportFonts.GetFont(GetPDFDocument(), bIsFieldName, false), nFontSize);

    blockComposer.Begin(GetRectangle(fMarginX, fMarginY, fWidth, nFontSize), AlignX, AlignY);
    int nIndex = blockComposer.ShowText(strText, false);
    blockComposer.End();

    ....

    composer.End();
    composer.Flush();
}

Screenshot Sample Report Page (redacted for client-privacy reasons): Sample Report Page


Solution

  • The Function: ReportFonts.GetFont(...) was creating a new font every single time it was called. This font was then stored in the dll's memory space and the final file which was what was taking up so much space.

    Used a Dictionary<> to solve the issue, not only is the memory space clean and the file size acceptable, but the execution time is also much improved.

    Moving to 64-bit also helped somewhat.