Skip to content

fix(PdfPageView): dispose the previous image before replacing it - #698

Merged
espresso3389 merged 1 commit into
espresso3389:masterfrom
bschmalb-ksta:fix/pdfpageview-image-leak
Aug 24, 2026
Merged

fix(PdfPageView): dispose the previous image before replacing it#698
espresso3389 merged 1 commit into
espresso3389:masterfrom
bschmalb-ksta:fix/pdfpageview-image-leak

Conversation

@bschmalb-ksta

Copy link
Copy Markdown
Contributor

Fixes #697.

_PdfPageViewState._updateImage overwrites _image without disposing the previous one, so every re-render that changes the requested page size (a zoom tier change, a layout change, a pageSizeCallback returning a new size) orphans a full-resolution decoded ui.Image. The only _image?.dispose() in the class is in _clearCache(), which this path never calls.

It also lacked a mounted guard on the assignment — the existing check only guarded setState. If the widget was disposed during the await, _clearCache() had already run and nulled _image, and the assignment then wrote a fresh image into a dead State where nothing would ever dispose it.

This is the second half of #110, which was closed as fixed in 1.0.51; only the dispose() half landed.

The fix matches what PdfViewer already does in pdf_viewer.dart (lines 1760-1764 and 1847-1852): guard on !mounted, dispose the old image, then swap.

final newImage = await pageImage.createImage();
pageImage.dispose();
if (!mounted) {
  newImage.dispose();
  return;
}
_image?.dispose();
_image = newImage;
setState(() {});

Kept deliberately minimal — no reformatting, no changelog entry (happy to add one if you'd like). I could not run dart analyze against the workspace locally: dependency resolution fails on meta (pdfium_flutter wants 1.17.0 via the Flutter SDK's flutter_test, pdfrx_engine wants ^1.18.0). That failure reproduces identically on unmodified master, so it is unrelated to this change.

_updateImage() replaced _image with the newly rendered image without
disposing the old one first. _clearCache() disposes _image, but that
method only runs from dispose()/didUpdateWidget(), never from this
re-render path, so every re-render (e.g. a size/zoom change) orphaned
a full-resolution dart:ui.Image.

Also add a mounted guard: if the State was disposed while awaiting
createImage(), _clearCache() already ran and nulled _image, so
assigning newImage afterwards would leak it into a dead State with
nothing left to dispose it.

PdfViewer already does both of these correctly; this brings
PdfPageView in line with it.

Refs espresso3389#110
@espresso3389
espresso3389 merged commit f5c4716 into espresso3389:master Aug 24, 2026
12 checks passed
@espresso3389

Copy link
Copy Markdown
Owner

This fix has been released in pdfrx 2.4.8.

Written by Codex

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.

PdfPageView leaks a ui.Image on every re-render (_updateImage never disposes the previous _image)

2 participants