4.8 KiB
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/mainmoved; final tracker is based on869661cbba. - 2026-05-29: Counted 3341 broad risk-pattern hits across
src,mobile,tests,config, andnativeon the final post-fix tree. - 2026-05-29: Re-ran heuristic buckets after fixes:
addEventListenerwithout same-fileremoveEventListener: 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.setIntervalwithoutclearInterval: 1 remaining, a test comment string.setTimeoutwithout same-fileclearTimeout: 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.tspnpm 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.tspnpm vitest run --config config/vitest.config.ts src/main/ipc/notifications.test.ts src/main/computer/permissions.test.tspnpm vitest run --config config/vitest.config.ts src/main/ipc/developer-permissions.test.tspnpm 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.tspnpm run typecheck:node