question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Memory consumption after rendering certain amount of pdfs

See original GitHub issue

Before you start - checklist

  • [x ] I followed instructions in documentation written for my React-PDF version
  • [x ] I have checked if this bug is not already reported
  • [x ] I have checked if an issue is not listed in Known issues

Description

After rendering certain amount of pdfs we see memory consumption is constantly growing and memory is never released.

According to chrome profiler most memory usage is due to

MessageHandler._onComObjOnMessage method

Here is a screenshot of profiling results

screen shot 2018-11-15 at 14 19 55

Its probably related to pdf.js itself, so first I filed an issue on pfd.js project.

initial pdf.js issue

It was reviewed and the result is that they dont consider this memory leak, unless react-pdf implementation doesn’t invoke ‘destroy’ method for ‘loadingTask’

https://github.com/mozilla/pdf.js/blob/960213cb6963f9bf46d6224805de2dc73fef0af4/src/display/api.js#L481-L498

And I see destroy for loadingTask is never invoked.

Here was my question to pdf.js

Is it right that we MUST call destroy() to avoid memory consumption and if we don’t it may lead to situation above?

And here is pdf.js guys answer to it

The loadingTask must be destroy()-ed in order to clean-up various resources, both on the main- and worker-threads.

I tried brief implementation of ‘destroy’ this way

// utils.js
export const makeCancellable = (promise) => {
  let isCancelled = false;

  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then(
      (...args) => (isCancelled ? reject(new PromiseCancelledException('Promise cancelled')) : resolve(...args)),
      error => (isCancelled ? reject(new PromiseCancelledException('Promise cancelled')) : reject(error)),
    );
  });

  return {
    promise: wrappedPromise,
    cancel() {
      isCancelled = true;
    },
    destroy() {
      if (typeof promise.destroy === 'function') {
        promise.destroy();
      }
    },
  };
};

// Document,jsx
componentWillUnmount() {
    this.runningTask.destroy();
    cancelRunningTask(this.runningTask);
  }

Its probably playing around of promises which is not right way to handle it, but anyway, it leads to no memory consumption,

promise is an instance of LoadingTask (PDFJS.getDocument(source)) and promise.destroy() is successfully invoked and releases resources, but is causing this error from time to time and i think its due my misunderstanding when is must be invoked.

pdf.worker.js:22726 Uncaught (in promise) Error: Worker was terminated
    at ensureNotTerminated (pdf.worker.js:22726)
    at onFailure (pdf.worker.js:22866)

I have selenium long running test, that shows memory is released with destroy method invoked, and is not released without it.

I think I dont understand the right pdf rendering flow to get loadingTask destroyed when it must be, but I believe this must be invoked as guys from pdf.js confirm this. Can we try clarifying the right flow - when loading task can be destroyed and is it finally the right approach to free resources.

this.runningTask = makeCancellable(PDFJS.getDocument(source));

this is pdf.js API wrapped into cancellable promise, and this API has ‘destroy’ method, that I referenced with a link earlier and that we never invoke.

Steps to reproduce

Steps to reproduce the behavior:

  1. Render pdf document with Document component.
  2. While rendering has not yet finished, unmount Document component and mount it again with new pdf source.
  3. See memory consumption

Expected behavior

Expect to see memory released

Additional information

Environment

  • Chrome 70.0
  • React-PDF version 3.0.5
  • React version 16.2.0

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

2reactions
quarrymancommented, Dec 10, 2018

@wojtekmaj I will try within a few hours and give our feedback. Thanx much for participating! We very appreciate your help.

0reactions
wojtekmajcommented, Apr 1, 2021

Please kindly check React-PDF v5.3.0-beta.2, in which improvements regarding memory management were made.

Let me know what you think in #748!

Read more comments on GitHub >

github_iconTop Results From Across the Web

79367 - Huge memory usage for rendering a PDF (1.1GB)
With Okular, the memory usage is fixed around 150 MB, but when one zooms the PDF, it has to be re-rendered, which is...
Read more >
Solved: HIGH MEMORY USAGE - 12231091
Go to Edit (Win), Adobe Acrobat (Mac) > Preferences > Page Display > Rendering > Uncheck 'Use page cache' > Click OK and...
Read more >
Improve pdf render speed - Super User
So, trade off CPU and RAM usage for disk usage... To do this, don't use PDFs; use pre-rendered images of the pages and...
Read more >
Issue 669 in pdfium: Memory leak when rendering pages.
1. Load the attached PDF into PDFium (Chrome is an easy way to test.) 2. Open Chrome's task manager and identify the starting...
Read more >
How to reduce memory consumption after printing a pdf file in ...
This works fine for small number of pages. But when the number of pages increases, the memory consumption for rendering the BitmapImages goes ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found