Skip to content

Fix a memory leak caused by uncollected QPdfDocument garbage#52

Merged
bmjcode merged 1 commit into
masterfrom
fix-qpdfdocument-memory-leak
May 5, 2026
Merged

Fix a memory leak caused by uncollected QPdfDocument garbage#52
bmjcode merged 1 commit into
masterfrom
fix-qpdfdocument-memory-leak

Conversation

@bmjcode
Copy link
Copy Markdown
Member

@bmjcode bmjcode commented May 4, 2026

When I wrote this code, I incorrectly assumed that QPdfDocument needed a parent QObject because it did not default to parent=None. For lack of a more convenient alternative, I used the application instance as the parent, which had the unfortunate effect of causing QPdfDocument objects to never go out of scope or be garbage-collected when no longer needed.

It turns out creating a QPdfDocument without a parent is apparently fine, and Qt's PDF API is just quirky and poorly documented.

This likely fixes frescobaldi/frescobaldi#2159.

When I wrote this code, I incorrectly assumed that QPdfDocument needed a
parent QObject because it did not default to parent=None. For lack of a
more convenient alternative, I used the application instance as the
parent, which had the unfortunate effect of causing QPdfDocument objects
to never go out of scope or be garbage-collected when no longer needed.

It turns out creating a QPdfDocument without a parent is apparently
fine, and Qt's PDF API is just quirky and poorly documented.

This likely fixes frescobaldi/frescobaldi#2159.
@fedelibre
Copy link
Copy Markdown
Member

I guess you know what you are doing so feel free to merge it when you think it's ready.

Do you need any testing from us?

@bmjcode
Copy link
Copy Markdown
Member Author

bmjcode commented May 4, 2026

I'm confident in the fix, but I'd always welcome more testing!

To see what this is doing, you can print() the renderer's cache keys before the load() function returns, since those happen to be weak references to the QPdfDocument objects:

        document.load(source)
        print("cache:", list(PdfRenderer.cache._cache.keys()))
        return document

Before this PR, each new engraving would add the QPdfDocument from the previous engraving to the cache, and memory usage would go up correspondingly. After this PR, only the most recent previous QPdfDocument should remain in cache after re-engraving, and memory usage should stay constant after the first re-engraving.

I've tested on my own Windows and Linux systems, but I'll wait until you all have had a chance to try just to be safe.

@ksnortum
Copy link
Copy Markdown

ksnortum commented May 4, 2026

I've been using this PR for several hours and no memory leaks or crashes! Great job!

@fedelibre
Copy link
Copy Markdown
Member

I did a test on the usual Chopin big file.

With 1.0.4 version of qpageview, the RAM grew quite fast from 250MB to 500MB after a few edits and compilations.
With this branch of qpageview, it grew much less: say, from 250MB to 340MB in the same number of edits+recompilations.

@bmjcode
Copy link
Copy Markdown
Member Author

bmjcode commented May 5, 2026

Cool, that's exactly what we want to see. Time to merge.

@bmjcode bmjcode merged commit 89225a3 into master May 5, 2026
3 checks passed
@bmjcode bmjcode deleted the fix-qpdfdocument-memory-leak branch May 5, 2026 11:08
@mspi21
Copy link
Copy Markdown

mspi21 commented May 7, 2026

I can confirm that using this commit of qpageview eliminates the issue described in frescobaldi/frescobaldi#2159. Is there a plan to make a release for this fix?

@fedelibre
Copy link
Copy Markdown
Member

Yes, we'll make a new release in the coming days.

@bmjcode Let me know if you have any other fixes for qpageview and when we can schedule a new qpageview+Frescobaldi release.

@bmjcode
Copy link
Copy Markdown
Member Author

bmjcode commented May 8, 2026

@fedelibre I have a couple more fixes under #53 and #54. Those should be enough for the new release.

@fedelibre
Copy link
Copy Markdown
Member

Ok, then I'll make a new qpageview release tomorrow and wait for you to merge those two open Frescobaldi PRs.

@bmjcode
Copy link
Copy Markdown
Member Author

bmjcode commented May 10, 2026

@fedelibre Let's add #56 to the new release too. It makes a huge difference at higher zoom levels.

These PRs are all slightly more complicated than planned because I'd start working on one thing and discover two more to fix, but I think the results are worth it. At any rate, they're ready to review now. I'm done nitpicking -- for now, anyway :)

Edit: All right, one more. #57 fixes a rather silly oversight that would nag at me forever if I didn't get it in the release.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Memory leak after extended use in 4.0.5

4 participants