Skip to content

Fix memory leak: replace JSDOM with lightweight DOM stub + graphics pool - #1

Merged
shakeelmohamed merged 8 commits into
mainfrom
mem-leak
Apr 10, 2026
Merged

Fix memory leak: replace JSDOM with lightweight DOM stub + graphics pool#1
shakeelmohamed merged 8 commits into
mainfrom
mem-leak

Conversation

@shakeelmohamed

Copy link
Copy Markdown
Member

Problem

Running p5.js sketches that call createGraphics() every frame caused unbounded heap growth (76MB → 700MB+). Two root causes:

  1. JSDOM — the full DOM implementation kept every canvas element alive in its internal node tree, preventing garbage collection.
  2. Per-frame Cairo surface allocation — each createGraphics() call allocated a new native Cairo instance, they were were released and therefore never garbage collected.

Key Changes

p5b-dom.js (new file) — P5bDOM class with a minimal DOM stub we have full ownership over. It canvases so lifecycle is fully under our control. This DOM stub is not exported in the library’s public API.

p5b.js

  • Replaced JSDOM with P5bDOM
  • Added _gfxPool (Map keyed by WxH dimensions) — createGraphics() is overridden to return a pooled p5.Graphics object when one is available, making zero new Cairo allocations after the first frame
  • toFrame() now uses Cairo’s native drawImage + toBuffer("raw") for scaling (BGRA→RGBA swap) instead of a JS pixel loop over the full source canvas
  • Overrode p5.Graphics.remove() to safely detach from the DOM stub without crashing in headless environments
  • Fixed _emitRuntimeError to always emit (was silently swallowing errors when no listener was attached)

package.json

  • Added p5b-dom.js to files
  • Removed jsdom dependency

Result

Heap memory stabilizes around 13–19MB (normal GC sawtooth), RSS tends to cap around 100–125mb before garbage collection kicks in. Previously heap memory grew monotonically at ~80KB/frame, and RSS memory grew several mb per second leading to OOM errors after a few hours.

@shakeelmohamed
shakeelmohamed merged commit c461139 into main Apr 10, 2026
1 check passed
@shakeelmohamed
shakeelmohamed deleted the mem-leak branch April 15, 2026 20:31
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.

1 participant