#1395·pdfplumber

page.page_obj retains pdfminer layout objects, causing ~390 MB memory leak per 170-page PDF even after flush_cache()

Author: yankerssnhCreated Sep 7, 2026Updated Sep 8, 2026
Labelsbug

Problem

When extracting text from many pages using pdfplumber, memory usage grows linearly with page count. flush_cache() does not release pdfminer layout objects stored in page.page_obj, causing significant memory retention (~390 MB for a 170-page report).

Reproduction

import pdfplumber import tracemalloc

tracemalloc.start()

pdf = pdfplumber.open("large_report.pdf") for page in pdf.pages: text = page.extract_text() page.flush_cache() # does NOT free page_obj

_, peak = tracemalloc.get_traced_memory() print(f"Peak: {peak / 1024 / 1024:.2f} MB")

Actual: ~591 MB after flush_cache() alone

Without flush: ~935 MB

Root Cause

page.page_obj (a pdfminer PDFPage object) holds layout/char data. flush_cache() clears Container.cached_properties (_rect_edges, _curve_edges, _edges, _objects) but does not clear _layout or the underlying page_obj. The Page class sets cached_properties = Container.cached_properties + ["_layout"], but flush_cache only iterates over the cached_properties passed to it (or the default), which in Container does not include _layout. Even if _layout is cleared, page_obj persists.

Fix

After extracting text/tables from each page:

page.flush_cache() page.get_textmap.cache_clear() page.page_obj = None

Impact

┌───────────────────────────────────────┬─────────────┐ │ │ Peak memory │ ├───────────────────────────────────────┼─────────────┤ │ Before fix │ 944.65 MB │ ├───────────────────────────────────────┼─────────────┤ │ After flush_cache() │ 591.86 MB │ ├───────────────────────────────────────┼─────────────┤ │ After flush_cache() + page_obj = None │ 26.69 MB │ └───────────────────────────────────────┴─────────────┘

Environment

  • pdfplumber 0.11.10
  • Python 3.14.2

Suggested Fix

Update Page.flush_cache() to also clear self.page_obj and self._layout if present, or document that users must manually set page.page_obj = None.