Renderer UndoRedoService._editStacks & ResourceEditStack._past grows unboundedly and leaks memory over long sessions
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
Does this issue occur when all extensions are disabled?: Yes
- VS Code Version: 1.107.1 (Node.js 22.21.1, V8 14.2.231.27-electron.0)
- OS Version: macOS (Darwin arm64 24.6.0)
Steps to Reproduce:
1. Generate a large file:
dd if=/dev/zero bs=1M count=500 | tr '\0' 'A' > /tmp/test_large.log
2. Open this file in VS Code.
3. In the file, perform the following actions:
a. `Ctrl+A` (or `Cmd+A` on macOS) to select all.
b. Type any character (e.g. `"x"`) — this produces a `TextChange.oldText` of roughly 500 MB.
c. `Ctrl+Z` (or `Cmd+Z`) to undo.
d. Type another character.
e. Repeat steps a–d 10–20 times.
4. Observe: the renderer process memory keeps climbing, and each select-all-and-replace cycle adds roughly 1 GB of retained memory (`oldText` + `newText`).
Expected:
`UndoRedoService._editStacks` stays bounded — entries for closed resources are released, and per-resource `_past` / `_future` stacks are trimmed by the configured element-count / total-size limits, so total retained memory stays flat over time.
Actual:
A heap snapshot from a long-running session shows `UndoRedoService._editStacks` alone retaining **~6.24 GB (36% of the renderer heap)**. Concrete evidence from the snapshot:
- `_editStacks: Map` retained size: **6,548,231 kB**.
- One specific `ResourceEditStack` entry (key `12`, allocation site `workbench/browser/parts/titlebar/titlebarPart.ts:361:1`) alone retains **6,545,726 kB** — i.e., a single resource is responsible for essentially all the growth.
- That entry's `_past: Array` has **at least 1,924 elements** (indices [1909]..[1924]+ visible, each `_Fe` element retaining 83–99 MB, monotonically decreasing with age).
- Each `_Fe` element retains a `KF` (`editor/common/core/edits/lineEdit.ts:342:35`) → `model: n_` (`tokens/treeSitter/tokenStore.ts`) → `_buffer: rAe` (`pieceTreeTextBuffer`) → `_pieceTree: z$s` → `_buffers: Array` chain, with `_buffers` retaining ~1.67 GB across many `D8` buffer objects created from `editor/common/model/textModelSearch.ts:312:40`.
Any suggestions on how to address this would be greatly appreciated.
Contributor guide
Assessment
This issue has not been assessed yet.