orca/docs/reference/memory-leak-audit-final-com...

4.8 KiB

Memory Leak Audit Final Comb

Started: 2026-05-29 PDT

Final tracker branch: nwparker/mem-leak-final-comb-tracker, based on origin/main at 869661cbba after the final-comb fix PRs merged.

Objective: run one more complete pass across the current Orca tree for missed listener, timer, observer, worker, socket, watcher, subscription, abort, and disposable leaks; open scoped PRs for confirmed stranglers; include risk level and merge low-risk PRs.

Codebase Inventory

Tracked code files, from git ls-files:

Bucket Files Status
src/renderer 1584 Checked
src/main 856 Checked
src/shared 245 Checked
mobile/src 100 Checked
tests/e2e 72 Checked
src/relay 65 Checked
src/cli 65 Checked
config/scripts 33 Checked
mobile/app 16 Checked
other-code 5 Checked
src/preload 6 Checked
mobile/packages 5 Checked
Total 3052 Checked

Scan Log

  • 2026-05-29: Created fresh final-comb branch from current origin/main.
  • 2026-05-29: Fast-forwarded the final-comb branch as origin/main moved; final tracker is based on 869661cbba.
  • 2026-05-29: Counted 3341 broad risk-pattern hits across src, mobile, tests, config, and native on the final post-fix tree.
  • 2026-05-29: Re-ran heuristic buckets after fixes:
    • addEventListener without same-file removeEventListener: 37 remaining. Reviewed as React Native subscriptions with .remove(), injected WebView document-lifetime scripts, { once: true } image load handlers, IPC abort-signal test listeners, singleton image-cache invalidation, owned pane-divider DOM, and test fixture listeners.
    • setInterval without clearInterval: 1 remaining, a test comment string.
    • setTimeout without same-file clearTimeout: 233 remaining. Reviewed remaining main-process hits as sleep helpers, intentional app relaunch/exit delays, socket idle timeout ownership, usage-scanner yield points, and startup force-exit behavior. Confirmed final-comb timer findings are fixed in PRs listed below.
    • Observers without disconnect: 0.
    • Workers without terminate: 0.
    • Abort controllers without abort: 1 test-only controller passed through the abortable API under test.
    • Watchers without close/unwatch: no production misses; remaining heuristic hits are provider type/comment references.
  • 2026-05-29: Re-ran React effect scan and spot-checked candidates. Remaining hits had cleanup returns (clearTimeout, clearInterval, removeEventListener, IPC unsubscribe) or were short one-shot UI focus/open delays.

Findings

PR Risk Status Finding Resolution
#3305 LOW Merged Browser reload fallback timer retained the reload promise closure, webContents reference, and listeners until the 10s fallback fired even after did-finish-load/did-fail-load. Clear the fallback timer on early settle, guard duplicate cleanup, and test with fake timers.
#3306 LOW Merged Native notification retention timers stayed scheduled after close/click cleanup, retaining notification closures until fallback expiry. Clear notification fallback timers on release, detach native listeners, and cover dispatch/startup/accessibility notification paths.
#3307 LOW Merged Local-network permission UDP prompt kept its 1s fallback timer and socket error listener after the send callback settled first. Clear the fallback timer, remove the error listener, and test the developerPermissions:request local-network path.

No higher-risk findings remained after the final pass, so no second higher-risk mitigation pass was needed.

Validation

  • pnpm vitest run --config config/vitest.config.ts src/main/browser/agent-browser-bridge.test.ts
  • pnpm vitest run --config config/vitest.config.ts src/main/browser/agent-browser-bridge.test.ts src/main/ipc/notifications.test.ts src/main/computer/permissions.test.ts src/main/ipc/developer-permissions.test.ts
  • pnpm vitest run --config config/vitest.config.ts src/main/ipc/notifications.test.ts src/main/computer/permissions.test.ts
  • pnpm vitest run --config config/vitest.config.ts src/main/ipc/developer-permissions.test.ts
  • pnpm exec oxlint src/main/browser/agent-browser-bridge.ts src/main/browser/agent-browser-bridge.test.ts src/main/ipc/notifications.ts src/main/ipc/notifications.test.ts src/main/computer/permissions.ts src/main/computer/permissions.test.ts src/main/ipc/developer-permissions.ts src/main/ipc/developer-permissions.test.ts
  • pnpm run typecheck:node