This is a migrated thread and some comments may be shown as answers.

Very high memory consumption while exporting RadFixedDocument with images to PDF

5 Answers 165 Views
PdfProcessing
This is a migrated thread and some comments may be shown as answers.
Mike Shilkov
Top achievements
Rank 1
Mike Shilkov asked on 30 Jan 2017, 02:08 PM

I am trying to export a number of images (up to several hundreds) into a PDF file (client-side in Silverlight). Here is a sample code that simulates this task:

// controlToExport is a control on the screen
RadBitmap bitmap = new RadBitmap(controlToExport);
for (int i = 0; i < 50; i++)
{
    var page = this.document.Pages.AddPage();
    page.Content.AddImage(new Telerik.Windows.Documents.Fixed.Model.Resources.ImageSource(bitmap.Bitmap));
}
// stream is User's file
var exportProvider = new Telerik.Windows.Documents.Fixed.FormatProviders.Pdf.PdfFormatProvider();
exportProvider.Export(this.document, stream);

 

This works but the export consumes ~500MB of memory while busy, which causes out-of-memory exceptions on lower end machines. How can I minimize the memory consumption.

In the real scenario, the loop will create many different images and will add them to the document instead of adding same image many times.

5 Answers, 1 is accepted

Sort by
0
Mike Shilkov
Top achievements
Rank 1
answered on 30 Jan 2017, 03:02 PM

My second attempt involved exporting each image as a separate PDF file, and then zipping them into archive. The code for each page looks like this:

var section = new Section();
section.Blocks.Add(new Paragraph { Inlines = { new ImageInline(bitmap.Bitmap) } });
section.PageSize = new Size(bitmap.Width, bitmap.Height + 115 /* Header + Footer */);
 
var document = new RadDocument
{
    Sections ={section}
};
var file = this.provider.Export(document);

 

It didn't help much though: with every image export the memory consumption grows (and doesn't seem to be released even after the archiving is done). If I comment out the call to provider.Export, it stops growing. What might be going on there?

0
Deyan
Telerik team
answered on 02 Feb 2017, 12:52 PM
Hello Mike,

When you add multiple images as pages they are preserved in memory until the RadFixedDocument instance is exported to PDF. This explains the high memory consumption. With the latest version of RadPdfProcessing, we have introduced a new approach for processing PDF files allowing you to write pages directly to PDF FileStream without the need of keeping the pages in memory through RadFixedDocument model. You may learn about this new functionality in this blog post, this documentation and this SDK example. You may also take a look at the following code snippet showing how to modify your first code snippet so that it uses the new PdfStreamWriter class:
using (PdfStreamWriter fileWriter = new PdfStreamWriter(stream))
{
    RadBitmap bitmap = new RadBitmap(controlToExport);
 
    for (int i = 0; i < 50; i++)
    {
        RadFixedPage page = new RadFixedPage();
        page.Size = new Size(bitmap.Width, bitmap.Height);

        FixedContentEditor editor = new FixedContentEditor(page);
        editor.DrawImage(new ImageSource(bitmap.Bitmap));
 
        fileWriter.WritePage(page);
    }
}

Additionally, if you need to optimize the memory consumption, make sure that the "stream" variable is a FileStream instance (created from SaveFileDialog in Silverlight), as this way you will write the PDF file directly to disk without consuming unnecessary memory.

I hope this helpful.

Regards,
Deyan
Telerik by Progress

0
Mike Shilkov
Top achievements
Rank 1
answered on 03 Feb 2017, 08:27 AM

Hello Deyan,

Thank you for your reply.

Indeed, my stream variable is the file from SaveFileDialog.

It will take some time for us to update to R1 2017, so I'll have to stick to the old way for now.

I got the second example working ok-ish with combination of RadFixedDocument and ZipArchive. But RadDocument that we used so far, still leaks the memory. Here is a complete example:

RadBitmap bitmap = new RadBitmap(controlToExport);
 
var section = new Section();
section.Blocks.Add(new Paragraph { Inlines = { new ImageInline(bitmap.Bitmap) } });
// ... Add more things to the document...
 
var document = new RadDocument
{
    Sections = { section }
};
 
PdfFormatProvider provider = new PdfFormatProvider();
provider.ExportSettings.ContentsCompressionMode = PdfContentsCompressionMode.Automatic;
provider.ExportSettings.ContentsDeflaterCompressionLevel = 9;
provider.ExportSettings.FloatingUIContainersExportMode = PdfInlineUIContainersExportMode.Image;
provider.ExportSettings.ImagesCompressionMode = PdfImagesCompressionMode.Automatic;
provider.ExportSettings.ImagesDeflaterCompressionLevel = 9;
provider.ExportSettings.InlineUIContainersExportMode = PdfInlineUIContainersExportMode.Image;
 
var file = provider.Export(document);

 

How can I release the memory after that? It seems to be consumed forever, even though we have no references to all those instances. Is there a Dispose somewhere?

0
Mihail
Telerik team
answered on 06 Feb 2017, 04:30 PM
Hello Mike,

I am afraid that I couldn't manage to reproduce the described memory leak related to RadDocument.
Could you please open a new support or forum thread regarding this memory leak for the RadRichTextBox control. I am asking this as this is the section for PdfProcessing.

It would be of great help if you could also provide more information to the new thread on how we could reproduce the problem. Like: 
1. How do you determine that there is a memory leak?
2. Is the memory leak reproduced without RadBitmap?
3. What additional elements do you add to the document before exporting?
4. Working sample project illustrating the problem.
5. A version of the used assemblies.

Any additional information you think is relevant is appreciated.

Regards,
Mihail
Telerik by Progress

0
Deyan
Telerik team
answered on 20 Mar 2017, 12:02 PM
Hello,

Just a quick follow-up regarding the low memory consumption of PdfStreamWriter approach. There used to be an issue with the caches of PdfStreamWriter class that was keeping unnecessarily some resources during the writing process. We have implemented optimizations in these caches in order to guarantee maximized memory optimizations when creating big documents with images. As you may see from this feedback item these optimizations implementation is included in LIB version 2017.1.320. You may use the attached project as an example for how to create big PDF file from big images with low memory consumption.

Regards,
Deyan
Telerik by Progress

Tags
PdfProcessing
Asked by
Mike Shilkov
Top achievements
Rank 1
Answers by
Mike Shilkov
Top achievements
Rank 1
Deyan
Telerik team
Mihail
Telerik team
Share this question
or