Spire.PDF is a professional PDF library applied to creating, writing, editing, handling and reading PDF files without any external dependencies. Get free and professional technical support for Spire.PDF for .NET, Java, Android, C++, Python.

Mon Apr 24, 2023 11:19 am

Hello,

I have an application that needs to manipulate the images from PDF files.

Here's a small sample code that contains the core of the code:

Code: Select all
        static void Main(string[] args)
        {
            AddVisibleWatermark_PDF("../../../images.pdf");
            Console.ReadLine();
        }


        public static bool AddVisibleWatermark_PDF(string filePath)
        {
            using (Spire.Pdf.PdfDocument pdf = new Spire.Pdf.PdfDocument())
            {
                pdf.LoadFromFile(filePath);

                if (pdf.Pages.Count > 0)
                {
                    int progressSteps = pdf.Pages.Count;
                    int currentStep = 1;

                    foreach (Spire.Pdf.PdfPageBase page in pdf.Pages)
                    {
                        Console.Write($"Processing page {currentStep} of {progressSteps}... ");

                        Image[] pageImages = page.ExtractImages();

                        for (var i = 0; i < pageImages.Length; i++)
                        {
                            try
                            {
                                if (pageImages[i].Width >= 300 && pageImages[i].Height >= 250)
                                {
                                    using (MemoryStream imageStream = new MemoryStream())
                                    {
                                        var imageFormat = pageImages[i].RawFormat.Guid == ImageFormat.MemoryBmp.Guid ? ImageFormat.Bmp : pageImages[i].RawFormat;
                                        pageImages[i].Save(imageStream, imageFormat);

                                        var finalStream = Spire.Pdf.Graphics.PdfImage.FromStream(imageStream);

                                        page.ReplaceImage(i, finalStream);

                                        finalStream.Dispose();
                                    }
                                }
                                //This doesn't seem to do anything
                                pageImages[i].Dispose();
                            }
                            catch (Exception ex)
                            {
                            }
                        }

                        //foreach (var image in pageImages)
                        //{
                        //    //This doesn't seem to do anything
                        //    image.Dispose();
                        //}

                        Console.WriteLine("Done");
                        currentStep++;
                    }

                }

                pdf.SaveToFile(filePath, Spire.Pdf.FileFormat.PDF);
 
                //These don't seem to do anything
                pdf.Close();
                pdf.Dispose();
            }

            return true;
        }


What happens is that after exiting the "AddVisibleWatermark_PDF" method, the memory usage is significantly high - this seems to indicate that none of the "dispose()" or "using" calls are doing anything.

Here are the specifics for the file I tested:
    File: I am not allowed to post URLs, but I can either share the file via PM or another large file with images can be used
    File Size: 72.5MB
    Memory usage after running "AddVisibleWatermark_PDF": 556MB

By looking at the memory heap, there are lots of objects still in memory, that weren't disposed.

Another relevant note is that even if I don't replace the images (if I just run "page.ExtractImages()" and optionally the commented "image.Dispose()" code), I get similar results.


Finally, here are remaining details:

    Version: 8.11.0 and 9.4.0
    OS: Windows 11/Windows 10/Windows Server 2016
    App Type: Console (Framework .NET 6.0)


I'd like to ask you if there's any way of disposing these objects - this becomes a significant problem when dealing with larger files (over 1GB), since the server runs out of memory very fast.

Thanks in advance!

jorge_fvf
 
Posts: 1
Joined: Mon Apr 24, 2023 10:29 am

Tue Apr 25, 2023 3:08 am

Hi,

Thanks for your feedback.
When our product calls the dispose() method, the memory is not immediately released. Instead, we release the resources and set the object reference to null, but the object still remains in the heap memory until it is automatically collected by the garbage collector (GC).

To further investigate this issue, we conducted a test on a PDF document with over 800 pages and a size of over 100 MB, using the lateset Spire.PDF (9.4.0). After the method was executed, we observed that the memory was properly released. Please refer to the following screenshots.
dispose.png

methodFinish.png

Could you please provide us with your test document? you can upload it to OneDrive or Google Drive and share the download link with us via email ([email protected]), thanks for your assistance.

Best regards,
Triste
E-iceblue support team
User avatar

Triste.Dai
 
Posts: 1000
Joined: Tue Nov 15, 2022 3:59 am

Return to Spire.PDF

cron