Skip to content

diag(crash): make renderer OOM profiles actionable - #10626

Closed
AmethystLiang wants to merge 10 commits into
mainfrom
crash-c1-heap-leak-diagnosis
Closed

AmethystLiang wants to merge 10 commits into
mainfrom
crash-c1-heap-leak-diagnosis

Conversation

@AmethystLiang

Copy link
Copy Markdown
Contributor

Summary

This PR makes the next renderer out-of-memory report identify which terminal subsystem is growing.

It does not claim to fix the underlying leak. It replaces stale/coarse memory sampling with precise trusted-renderer measurements, records four staged high-water profiles, and adds production diagnostics for terminal membership, xterm buffer weight, renderer output backlog, and pending PTY side effects.

Why the previous data was misleading

Electron 43.1.0 embeds Chromium 150. In that build, Chromium's MemoryInfo::GetHeapSize reports V8 used_heap_size() plus external_memory(). Therefore performance.memory.usedJSHeapSize is not a pure JavaScript-object heap measurement. xterm's Uint32Array row backing stores contribute through V8 external memory and remain a plausible source of the observed growth.

Without --enable-precise-memory-info, Chromium also quantizes performance.memory into geometric buckets and caches it for about 20 minutes. That means the field traces could establish sustained growth, but could not distinguish a boot burst, smooth leak, short GC sawtooth, or exact climb rate within each cache window.

Aggregate review of 57 crash bundles found:

  • 34 reached the investigation's high-memory band.
  • High-memory reports appeared on all supported desktop platforms.
  • Recorded Git activity was neither necessary nor sufficient.
  • Browser guest count alone did not correlate.
  • Repeated post-reload growth proves an external or reconstructible driver, but not automatic restoration of the prior mounted-worktree set: the renderer-local mount set resets and initially contains only the active worktree.

The leading hypothesis remains retained, streaming xterm buffers in mounted worktrees, but it is provisional. Other candidates are the uncapped PTY side-effect queue, renderer output/backpressure, and large passive editor/diff text working sets.

What changed

  • Enable precise performance.memory readings before trusted Orca renderer processes start.
  • Preserve Chromium's allocation/GC timing mitigation for arbitrary sites by disabling Blink PreciseMemoryInfo in every browser guest path:
    • desktop <webview> contents, including attach-time hardening;
    • offscreen browser windows;
    • guest-created popup contents.
  • Expand renderer high-water profiles from 60%/80% to 40%/60%/75%/85%.
  • Retain all four thresholds for both trusted renderer surfaces and clear retained profiles after a renderer process dies, so a replacement renderer cannot inherit the dead process's profile.
  • Attribute process-gone breadcrumbs to the renderer surface that produced them.
  • Replace created - disposed = live arithmetic with truthful terminal metrics:
    • cumulative registered, removed, and disposeErrors;
    • current pane-manager tracked membership;
    • connected/disconnected tracked DOM containers;
    • xterm bufferRows, scrollbackRows, and estimatedBufferCells.
  • Add production output-queue metrics for current/peak queued terminals and characters plus lossy backlog drops.
  • Add ptySideEffects.processors and ptySideEffects.pending gauges, disposed with their owning transports.
  • Raise retained breadcrumb capacity from four to eight and cover interleaved main/popout thresholds.

How to read the next profile

  • Rising paneTerminals.tracked and estimatedBufferCells with memory supports mounted-terminal retention.
  • Stable terminal count with rising rows/cells supports an active-tab or tab-local variant.
  • Rising ptySideEffects.pending with flat buffer weight supports the side-effect queue hypothesis.
  • Rising output backlog/peaks supports renderer delivery or parsing backpressure.
  • Flat terminal and queue metrics would push investigation toward large strings or another subsystem.

Screenshots

No visual change.

Testing

  • pnpm lint
  • pnpm typecheck
  • pnpm test — 3,411 files passed; 36,229 tests passed; 62 skipped
  • pnpm build — not run; typecheck and the complete unit/integration suite passed
  • Added regression coverage for precise-memory startup, all untrusted guest paths, four-threshold retention across both renderer surfaces, process-generation cleanup, terminal lifecycle semantics, pane-manager buffer aggregation, output-queue current/peak gauges, and PTY side-effect gauge disposal.

AI Review Report

The review checked the measurement model, reload lifecycle, browser security boundary, terminal census semantics, breadcrumb retention, public-data disclosure, formatting, and comments.

It flagged and this PR addresses:

  • usedJSHeapSize was incorrectly described as excluding typed-array backing stores.
  • H1 and same-mounted-set reload claims were overstated.
  • the process-global precise-memory switch exposed arbitrary browser contents;
  • arithmetic terminal “liveness” did not represent reachability;
  • creation/disposal counters could misstate construction failures and caught disposal errors;
  • retained breadcrumb capacity was too small for four thresholds across two surfaces;
  • the investigation document contained field identifiers and was moved to ignored local design-docs/ rather than included in the public diff.

Cross-platform review covered macOS, Linux, and Windows. This PR changes no shortcuts, labels, shell commands, or path handling. Electron-specific behavior is shared across platforms and tested at each guest-creation seam. The diagnostics read existing renderer state and apply equally to local, SSH, remote-runtime, git-worktree, and folder workspaces.

Security Audit

The main security risk was Chromium's process-global enable-precise-memory-info switch, which can expose allocation and GC timing to untrusted pages. The shared guest policy explicitly disables Blink PreciseMemoryInfo for webviews, offscreen windows, and popup contents; popup descendants inherit the same hardened creation policy. Trusted Orca UI surfaces keep precise diagnostics.

The new crash fields contain bounded numeric counts only—no terminal output, paths, URLs, profile names, tokens, or buffer contents. Contributor counts remain subject to the existing crash-profile budgets. No dependency, authentication, command-execution, or new IPC surface is introduced.

Notes

This is diagnosis instrumentation, not the final leak fix. The next precise field cycle should determine whether to implement a memory-weighted mounted-terminal budget, cap/collapse pending side effects, backport remote delivery-credit behavior, or profile large retained strings.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The changes configure precise renderer memory behavior through shared guest preferences and a startup Chromium switch. Crash diagnostics now use four high-water thresholds, retain up to eight entries, and clear renderer-specific retained breadcrumbs between crashes. Renderer profiling adds PTY side-effect gauges, terminal output queue peak and backlog metrics, pane terminal lifecycle counters, and aggregated pane buffer and connection metrics. Associated tests cover configuration, retention, lifecycle cleanup, queue behavior, and profiling output.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly reflects the main change: improving renderer OOM diagnostics.
Description check ✅ Passed The description follows the required template and covers summary, screenshots, testing, AI review, security audit, and notes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/main/browser/offscreen-browser-backend.web-preferences.test.ts (1)

27-30: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Retain the offscreen-backend wiring assertion.

toMatchObject only validates the imported constant; it does not prove that offscreen-browser-backend.ts still applies ORCA_BROWSER_GUEST_WEB_PREFERENCES. Keep the source/runtime integration assertion and add this value check rather than replacing it, so a regression could not silently re-enable precise memory reporting for offscreen guests.

src/renderer/src/components/terminal-pane/pty-transport.ts (1)

912-916: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Gauge disposal isn't guaranteed on every teardown path, and the registry has no defensive cap. disposePendingSideEffectGauge() is only invoked from detach()/destroy() in pty-transport.ts; the normal PTY-exit handler doesn't call it, and if that's a path by which a transport is discarded without a later destroy(), its gauge (and the pendingSideEffects closure) leaks forever in pty-side-effect-pending-census.ts's uncapped pendingGauges Set — undermining the very leak diagnostics this feature adds.

  • src/renderer/src/components/terminal-pane/pty-transport.ts#L912-L916: confirm the pane/lifecycle layer always calls destroy() after a PTY exit even outside the detach hand-off flow, or call disposePendingSideEffectGauge() from the exit handler itself as a safety net.
  • src/renderer/src/components/terminal-pane/pty-side-effect-pending-census.ts#L4-L19: consider bounding pendingGauges (mirroring registerRendererMemoryProfileContributor's MAX_PROFILE_CONTRIBUTORS cap) so a missed disposal degrades gracefully instead of growing unbounded.
src/renderer/src/lib/pane-manager/pane-terminal-output-queue-production-profile.test.ts (1)

41-51: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test doesn't prove the instantaneous snapshot fields work in production — only the peaks.

The assertions run after a full drain (vi.advanceTimersByTime(1000)), so queuedChars === 0 etc. would pass identically whether or not readQueueDebugSnapshot()'s instantaneous fields (terminals, queuedChars, maxQueuedCharsPerTerminal) actually work outside e2e — a drained queue reports 0 either way. Given this file's stated purpose is proving production visibility of the whole contributor, consider also asserting the non-zero snapshot values immediately after writeTerminalOutput (before advancing timers) to confirm readQueueDebugSnapshot() isn't itself gated behind e2e-only debug state.

✅ Suggested additional assertion
     writeTerminalOutput(createTerminal(), 'q'.repeat(32 * 1024), {
       foreground: false,
       latencySensitive: false
     })
+    expect(collectRendererMemoryProfileCounts()).toEqual(
+      expect.objectContaining({
+        'terminalOutputQueue.terminals': 1,
+        'terminalOutputQueue.queuedChars': 32 * 1024,
+        'terminalOutputQueue.maxQueuedCharsPerTerminal': 32 * 1024
+      })
+    )
     vi.advanceTimersByTime(1000)

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bf35fb0-7b19-4bc1-9dd1-2b958da8673c

📥 Commits

Reviewing files that changed from the base of the PR and between 468f5b7 and 8edf016.

📒 Files selected for processing (28)
  • src/main/browser/browser-manager.test.ts
  • src/main/browser/browser-manager.ts
  • src/main/browser/offscreen-browser-backend.web-preferences.test.ts
  • src/main/crash-reporting/crash-breadcrumb-store.test.ts
  • src/main/crash-reporting/crash-breadcrumb-store.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts
  • src/main/crash-reporting/process-gone-recorder.ts
  • src/main/index.ts
  • src/main/startup/renderer-heap-headroom.test.ts
  • src/main/startup/renderer-heap-headroom.ts
  • src/main/window/createMainWindow.test.ts
  • src/renderer/src/components/browser-pane/BrowserPane.webview-preferences.test.ts
  • src/renderer/src/components/terminal-pane/pty-side-effect-pending-census.test.ts
  • src/renderer/src/components/terminal-pane/pty-side-effect-pending-census.ts
  • src/renderer/src/components/terminal-pane/pty-transport.ts
  • src/renderer/src/lib/crash-diagnostics.test.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/renderer/src/lib/pane-manager/pane-lifecycle.test.ts
  • src/renderer/src/lib/pane-manager/pane-lifecycle.ts
  • src/renderer/src/lib/pane-manager/pane-manager-registry.test.ts
  • src/renderer/src/lib/pane-manager/pane-manager-registry.ts
  • src/renderer/src/lib/pane-manager/pane-manager.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-instance-census.test.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-instance-census.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-queue-production-profile.test.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.test.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.ts
  • src/shared/browser-guest-web-preferences.ts

Comment thread src/main/crash-reporting/process-gone-recorder.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 836367eb-c4b4-4f10-9f1d-0eebb74f66fe

📥 Commits

Reviewing files that changed from the base of the PR and between 8edf016 and 5f2c983.

📒 Files selected for processing (11)
  • src/main/crash-reporting/crash-breadcrumb-store.test.ts
  • src/main/crash-reporting/crash-breadcrumb-store.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts
  • src/main/crash-reporting/process-gone-recorder.ts
  • src/renderer/src/components/terminal-pane/parked-terminal-byte-watcher.test.ts
  • src/renderer/src/components/terminal-pane/parked-terminal-byte-watcher.ts
  • src/renderer/src/components/terminal-pane/remote-runtime-pty-transport.test.ts
  • src/renderer/src/components/terminal-pane/remote-runtime-pty-transport.ts
  • src/renderer/src/lib/crash-diagnostics.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.ts
  • src/shared/crash-reporting.ts
💤 Files with no reviewable changes (1)
  • src/renderer/src/lib/pane-manager/pane-terminal-output-scheduler.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/crash-reporting/process-gone-recorder.ts
  • src/renderer/src/lib/crash-diagnostics.ts

Comment thread src/main/crash-reporting/crash-breadcrumb-store.ts Outdated
@AmethystLiang

Copy link
Copy Markdown
Contributor Author

@coderabbitai[bot] addressed

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@AmethystLiang Thanks for addressing it! 🐇


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/crash-reporting/process-gone-recorder.ts (1)

114-128: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Scope retry carryover to the renderer surface.

key omits rendererSurface, while breadcrumbs contains profiles from every surface. A failed main report can therefore carry a popout profile; if the popout clears before the retry, Lines 125-128 merge that stale profile back. Use a renderer-surface-scoped dedupe/carry key and stash only the dead surface’s profiles.

Also applies to: 172-174


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 678f66f6-eb46-4669-a8a9-8b46f98776fa

📥 Commits

Reviewing files that changed from the base of the PR and between 5f2c983 and 13f2215.

📒 Files selected for processing (7)
  • src/main/crash-reporting/crash-breadcrumb-store.test.ts
  • src/main/crash-reporting/crash-breadcrumb-store.ts
  • src/main/crash-reporting/process-gone-dedupe.ts
  • src/main/crash-reporting/process-gone-highwater-carryover.test.ts
  • src/main/crash-reporting/process-gone-highwater-carryover.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts
  • src/main/crash-reporting/process-gone-recorder.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/crash-reporting/process-gone-recorder.test.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/crash-reporting/process-gone-recorder.test.ts (1)

427-458: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Prove the stash remains available to the matching surface.

This passes if failed persistence never stashes carryover. After the popout attempt, add a main-surface retry and assert its persisted breadcrumbs include the 85% highwater; this verifies both stashing and non-consumption by the sibling.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 499dd5c9-a8e6-4b59-96a2-ede565ed0e03

📥 Commits

Reviewing files that changed from the base of the PR and between 13f2215 and fa72950.

📒 Files selected for processing (6)
  • src/main/crash-reporting/crash-breadcrumb-store.ts
  • src/main/crash-reporting/process-gone-highwater-carryover.test.ts
  • src/main/crash-reporting/process-gone-highwater-carryover.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts
  • src/main/crash-reporting/process-gone-recorder.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-queue-production-profile.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/crash-reporting/process-gone-highwater-carryover.ts
  • src/renderer/src/lib/pane-manager/pane-terminal-output-queue-production-profile.test.ts
  • src/main/crash-reporting/process-gone-recorder.ts
  • src/main/crash-reporting/crash-breadcrumb-store.ts

@AmethystLiang

Copy link
Copy Markdown
Contributor Author

@coderabbitai[bot] addressed

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@AmethystLiang Thanks for addressing this.

@AmethystLiang

Copy link
Copy Markdown
Contributor Author

@coderabbitai[bot] addressed

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@AmethystLiang Thanks for addressing this.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0e073c80-8e05-4a9e-868e-87c8b600c55b

📥 Commits

Reviewing files that changed from the base of the PR and between fa72950 and 1721e5f.

📒 Files selected for processing (5)
  • src/main/crash-reporting/process-gone-highwater-carryover.test.ts
  • src/main/crash-reporting/process-gone-highwater-carryover.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts
  • src/renderer/src/lib/crash-diagnostics.test.ts
  • src/renderer/src/lib/crash-diagnostics.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/crash-reporting/process-gone-highwater-carryover.ts
  • src/main/crash-reporting/process-gone-recorder.test.ts

Comment thread src/renderer/src/lib/crash-diagnostics.ts
AmethystLiang and others added 10 commits August 5, 2026 15:11
C1_DIAGNOSIS.md: the field performance.memory samples are Chromium-bucketized
(~6% geometric) AND cached 20 minutes, so every published climb rate was a
20-min average; primary root-cause candidate is the mounted-worktree retention
policy (activated worktrees never unmount; SSH/remote/null-ptyId worktrees
bypass the cold-park cap and TTL entirely).

Instrumentation so the next field crash names the accumulator:
- enable-precise-memory-info switch (unbuckets + unfreezes the sampler)
- highwater ladder [0.6,0.8] -> [0.4,0.6,0.75,0.85]
- paneTerminals created/disposed/live census contributor
- terminalOutputQueue backlog contributor (production-visible)

Co-authored-by: Orca <help@stably.ai>
…r ladder

The 4-level ladder ([0.4, 0.6, 0.75, 0.85]) needs 4 thresholds x 2 renderer
surfaces of retained keys, but MAX_RETAINED_BREADCRUMBS stayed at 4 (sized for
the old 2-level ladder). Retained highwater breadcrumbs never fall back into
the 30-entry ring, so eviction silently dropped the low-threshold baseline the
ladder was widened to produce.

Also:
- pin the census create/dispose call sites and the terminalOutputQueue
  contributor with tests; only the census counters were covered
- correct the diagnosis doc's H2 label on the pane-terminal census (it tests
  H1) and the census docstring's detached-terminal claim
- note that the precise-memory switch is process-global and reaches
  browser-pane webview guests (behavior unchanged)
- move the diagnosis doc under docs/ next to its sibling profile writeup and
  drop the machine-specific corpus path
pendingSideEffects is the one uncapped hot-path queue (64/tick drain vs a
background-throttled ~1 Hz timer; pause cancels the drain without clearing) —
the C1 H2 suspect the existing contributors cannot see. Each output processor
registers a pending-count gauge; transports dispose it on detach()/destroy().

Co-authored-by: Orca <help@stably.ai>
…uced them

Two ways the C1 instrumentation could report the wrong thing:

Retained high-water profiles are keyed by surface+threshold with no renderer
generation, and nothing dropped them when a renderer died. Because a reload
resets the renderer-side one-shot guard while the main-process store survives,
a fresh renderer that died before re-crossing its ladder inherited the dead
one's ~3 GB profiles — the "OOM kill at a tiny heap" misreading the diagnosis
attributes to the existing corpus. Clear them at process-gone for renderers.

terminalOutputQueue reported instantaneous gauges only, sampled at most once
per threshold on a 60 s cadence, so a backlog that spiked and drained in
between read as zero — indistinguishable from "never grew". Add O(1) high-water
marks on the enqueue path and an ungated dropped-backlog counter; the peaks are
the sampling-immune half of the H3 signal, and the drop count is the strongest
evidence the lossy cap fired at all.

Both regressions are covered by revert-proven tests, including a non-e2e suite
since the sibling scheduler tests mock exposeStore=true and cannot see the
production path.
- remote PTY transport disposes its pending side-effect gauge on detach and
  destroy, matching the IPC transport; parked byte watchers dispose theirs too
- process-gone clears retained high-water profiles on any renderer generation
  end, including suppressed reloads and non-crash exits, not just recorded ones
- a failed persist re-seeds the cleared profiles so the retry's durable report
  still carries the OOM ladder
- the clear is scoped to the dead surface so a live dashboard popout keeps its
  own profiles (it never re-emits them)
The re-seed put cleared profiles back into the live store, so a retry that
never arrived left the next renderer's crash report carrying a dead
generation's ladder. Stash them against the dedupe key with the dedupe
window as TTL instead, and merge inside the 30-breadcrumb report budget.
The retry carryover key omits the surface, so sibling surfaces can share
it. Without scoping, a popout dying inside the window would inherit the
main renderer's stashed heap ladder. Carry only profiles belonging to
the dying surface (and unattributed ones that have no owner).
Dedupe key omits surface, so sibling surfaces (main/dashboard-popout)
dying the same way would share stash. Scope the carryover key by
surface so each surface owns its breadcrumbs independently; a
sibling's failed persist no longer evicts the other's profiles.
Early memory warnings at 40–60% heap now skip expensive DOM walks and subsystem profiling, emitting only lightweight heap metrics. Detailed diagnostics with DOM counts and store snapshots kick in only at 75%+ to reduce overhead on healthy sessions while preserving diagnostic value when approaching OOM.
@AmethystLiang
AmethystLiang force-pushed the crash-c1-heap-leak-diagnosis branch from b04a8f3 to 219d85a Compare August 5, 2026 22:16
@AmethystLiang

AmethystLiang commented Aug 5, 2026 •

Copy link
Copy Markdown
Contributor Author

too large. used a smaller PR #12795

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