Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Trigger cleanup, once rendering has finished, in PDFThumbnailView.draw #12613

Merged
merged 2 commits into from
Nov 12, 2020

Conversation

Snuffleupagus
Copy link
Collaborator

This patch will help reduce memory usage, especially for longer documents, when the user scrolls around in the thumbnailView (in the sidebar).

Note how the PDFPageProxy.cleanup method will, assuming it's safe to do so, release main-thread resources associated with the page. These include things such as e.g. image data (which can be arbitrarily large), and also the operatorList (which can also be quite large).
Hence when pages are evicted from the PDFPageViewBuffer, on the BaseViewer-instance, the PDFPageView.destroy method is invoked which will (among other things) call PDFPageProxy.cleanup in the API.

However, looking at the PDFThumbnailViewer/PDFThumbnailView classes you'll notice that there's no attempt to ever call PDFPageProxy.cleanup, which implies that in certain circumstances we'll essentially keep all resources allocated permanently on the PDFPageProxy-instances in the API.
In particular, this happens when the users opens the sidebar and starts scrolling around in the thumbnails. Generally speaking you obviously need to keep all thumbnail images around, since otherwise the thumbnailView is useless, but there's still room for improvement here.

Please note that the case where a rendered page is used to create the thumbnail is (obviously) completely unaffected by the issues described above, and this rather only applies to thumbnails being explicitly rendered by the PDFThumbnailView.draw method.
For the latter case, we can fix these issues simply by calling PDFPageProxy.cleanup once rendering has finished. To prevent accidentally pulling the rug out from under PDFPageViewBuffer in the viewer, which expects data to be available, this required adding a couple of new methods[1] to enable checking that it's indeed safe to call PDFPageProxy.cleanup from the PDFThumbnailView.draw method.

It's really quite fascinating that no one has noticed this issue before, since it's been around since basically "forever".


[1] While it should be very rare for PDFThumbnailView.draw to be called for a pageView that's also in the PDFPageViewBuffer, given that pages are rendered before thumbnails and that the rendered page is used to create the thumbnail, it can still happen since rendering is asynchronous.
Furthermore, it's also possible for PDFThumbnailView.setImage to be disabled, in which case checking the PDFPageViewBuffer for active pageViews really matters.

This patch will help reduce memory usage, especially for longer documents, when the user scrolls around in the thumbnailView (in the sidebar).

Note how the `PDFPageProxy.cleanup` method will, assuming it's safe to do so, release main-thread resources associated with the page. These include things such as e.g. image data (which can be arbitrarily large), and also the operatorList (which can also be quite large).
Hence when pages are evicted from the `PDFPageViewBuffer`, on the `BaseViewer`-instance, the `PDFPageView.destroy` method is invoked which will (among other things) call `PDFPageProxy.cleanup` in the API.

However, looking at the `PDFThumbnailViewer`/`PDFThumbnailView` classes you'll notice that there's no attempt to ever call `PDFPageProxy.cleanup`, which implies that in certain circumstances we'll essentially keep all resources allocated permanently on the `PDFPageProxy`-instances in the API.
In particular, this happens when the users opens the sidebar and starts scrolling around in the thumbnails. Generally speaking you obviously need to keep all thumbnail *images* around, since otherwise the thumbnailView is useless, but there's still room for improvement here.

Please note that the case where a *rendered page* is used to create the thumbnail is (obviously) completely unaffected by the issues described above, and this rather only applies to thumbnails being explicitly rendered by the `PDFThumbnailView.draw` method.
For the latter case, we can fix these issues simply by calling `PDFPageProxy.cleanup` once rendering has finished. To prevent *accidentally* pulling the rug out from under `PDFPageViewBuffer` in the viewer, which expects data to be available, this required adding a couple of new methods[1] to enable checking that it's indeed safe to call `PDFPageProxy.cleanup` from the `PDFThumbnailView.draw` method.

It's really quite fascinating that no one has noticed this issue before, since it's been around since basically "forever".

---
[1] While it should be *very* rare for `PDFThumbnailView.draw` to be called for a pageView that's also in the `PDFPageViewBuffer`, given that pages are rendered before thumbnails and that the *rendered page* is used to create the thumbnail, it can still happen since rendering is asynchronous.
Furthermore, it's also possible for `PDFThumbnailView.setImage` to be disabled, in which case checking the `PDFPageViewBuffer` for active pageViews *really* matters.
@timvandermeij
Copy link
Contributor

/botio-linux preview

@pdfjsbot
Copy link

From: Bot.io (Linux m4)


Received

Command cmd_preview from @timvandermeij received. Current queue size: 0

Live output at: http://54.67.70.0:8877/15fd49953e7eaf4/output.txt

@pdfjsbot
Copy link

From: Bot.io (Linux m4)


Success

Full output at http://54.67.70.0:8877/15fd49953e7eaf4/output.txt

Total script time: 4.07 mins

Published

@timvandermeij timvandermeij merged commit 59b3560 into mozilla:master Nov 12, 2020
@timvandermeij
Copy link
Contributor

Interesting find; thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants