microsoft / microsoft/vscode

Agents window: background session terminals keep their renderer-side xterm alive, growing unbounded

Open
#327,437 0 comments 1 reaction 1 assignee Claimed by @roblourens View on GitHub
Dominant language
TypeScript
Stars
193k
Forks
42.4k
PR merge metrics
PR metrics pending

Description

Found while analyzing a renderer heap snapshot from the Agents window (484 MB self-size).

## Summary

**80 MB (~16% of the renderer heap)** was xterm buffer data: 10,791 `JSArrayBufferData` allocations traced to `xterm ... _core._inputHandler._activeBuffer.lines._array[]._data → Uint32Array`.

There were **38 live `XtermTerminal` instances** (76 `_activeBuffer` roots = 38 terminals × normal + alternate buffer), which matches `SessionsTerminalContribution` exactly: ~33 entries in `_sessionTerminals` plus ~7 in `_standaloneTerminalIds`.

## This is by design, but it doesn't scale

`SessionsTerminalContribution` (`src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.ts`) distinguishes two paths:

- **Session removed** → `_closeTerminalsForSession` → `safeDisposeTerminal` (pty torn down).
- **Session archived / "Mark as Done"** → `_hideTerminalsForSession` → `_terminalService.moveToBackground` — deliberately keeps both the pty *and* the frontend xterm alive so unarchiving is instant.

Since archiving is the common flow and removal is rare, the live xterm count grows monotonically with the number of sessions ever opened, at roughly **1 MB each** (default 1000-line scrollback × cols × 4 bytes per cell).

At 38 sessions this is 80 MB. Someone with a few hundred archived sessions would be well into the hundreds of MB, purely in renderer-side scrollback for terminals that aren't visible.

## Options

1. **Release the renderer-side xterm for backgrounded terminals, keep the pty.** The pty host already replays scrollback on re-attach, so the content is recoverable. This is the correct fix but requires teaching `TerminalInstance` to drop `_xterm` when moved to background and lazily recreate it, which touches shared terminal code.
2. **LRU cap on background session terminals.** Keep the N most recently used xterms hydrated, dispose the rest. Cheaper, bounded, and mostly invisible in practice.
3. **Lower scrollback for backgrounded terminals.** Cheapest stopgap, proportional rather than bounded savings.

## Effort estimate

Medium. Option 2 is contained within `sessionsTerminalContribution.ts`; option 1 is the real fix but spans `vs/workbench/contrib/terminal`.

Lowest priority of the three memory issues from this snapshot — it's a design tradeoff rather than a leak, and 80 MB is the smallest of the three.

(Written by Copilot)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.