Bug Description
Several memory leaks occur during long-running opencode sessions, causing RSS to grow continuously:
-
AsyncQueue never terminates (util/queue.ts) - [Symbol.asyncIterator] loops forever with no close mechanism, preventing GC of consumers.
-
Bash tool unbounded string concatenation (tool/bash.ts:167-189) - stdout/stderr appended via output += chunk.toString() with no size limit. Commands producing large output (e.g., find /) cause unbounded memory growth.
-
LSP diagnostics Map never cleared (lsp/client.ts:51) - diagnostics Map accumulates entries indefinitely. shutdown() disposes the connection but doesn't clear the map.
-
Bus subscriptions Map not cleared on dispose (bus/index.ts) - Instance dispose callback fires wildcard subscribers but never calls subscriptions.clear().
-
PTY buffer string concatenation (pty/index.ts:136-150) - session.buffer += data then session.buffer.slice(-BUFFER_LIMIT) causes repeated large string allocation and GC pressure.
-
Instance.disposeAll() not called on process exit (index.ts) - The main finally block calls process.exit() without disposing instances, leaking subprocess handles.
Reproduction
- Start opencode, run a command producing large output (
find / -name "*.ts")
- Monitor with
top -pid <PID> - RSS grows without bound
- Idle for 10+ minutes - memory does not decrease
Environment
- opencode v1.1.36
- macOS Darwin 24.6.0
- Bun 1.3.5