Memory leak #6635

Open
opened 2026-02-16 18:04:49 -05:00 by yindo · 2 comments
Owner

Originally created by @amat27 on GitHub (Jan 17, 2026).

Originally assigned to: @rekram1-node on GitHub.

Description

more than 30Gig memory used after coding for about a morning. windows 11. using copilot provider

Plugins

none

OpenCode version

1.1.21

Steps to reproduce

coding work for half a day

Screenshot and/or share link

Image

Operating System

windows 11

Terminal

windows terminal

Originally created by @amat27 on GitHub (Jan 17, 2026). Originally assigned to: @rekram1-node on GitHub. ### Description more than 30Gig memory used after coding for about a morning. windows 11. using copilot provider ### Plugins none ### OpenCode version 1.1.21 ### Steps to reproduce coding work for half a day ### Screenshot and/or share link <img width="997" height="169" alt="Image" src="https://github.com/user-attachments/assets/5463dd8e-66bb-42cb-9e19-e3a9fb6967eb" /> ### Operating System windows 11 ### Terminal windows terminal
yindo added the windowsbugperf labels 2026-02-16 18:04:49 -05:00
Author
Owner

@github-actions[bot] commented on GitHub (Jan 17, 2026):

This issue might be a duplicate of existing issues. Please check:

  • #7046: memory leak
  • #5700: Too high memory usage
  • #5363: opencode eating 70gb of memory?

Feel free to ignore if none of these address your specific case.

@github-actions[bot] commented on GitHub (Jan 17, 2026): This issue might be a duplicate of existing issues. Please check: - #7046: memory leak - #5700: Too high memory usage - #5363: opencode eating 70gb of memory? Feel free to ignore if none of these address your specific case.
Author
Owner

@LIHUA919 commented on GitHub (Jan 18, 2026):

Based on my analysis of the recent memory leak fixes, here are the root causes:

Root Causes

1. TUI Footer Timeout Leak (#8255)

The footer component creates recursive timeouts but only cleans up the last one:

// Before (leak):
let timeout = setTimeout(() => tick(), 10000)
onCleanup(() => clearTimeout(timeout))  // Only clears last timeout

// After (fixed):
const timeouts = []
timeouts.push(setTimeout(() => tick(), 10000))
onCleanup(() => timeouts.forEach(clearTimeout))  // Clears all

Hundreds of uncleaned timers accumulate over time.

2. MCP Client Not Closed (#8253)

When reinitializing MCP clients, the old one was overwritten without closing:

// Before (leak):
s.clients[name] = result.mcpClient  // Old client still active!

// After (fixed):
await existingClient?.close()
s.clients[name] = result.mcpClient

This is especially critical for Copilot users since it uses the MCP protocol.

3. State Instance Not Removed from Map (#8252)

// Before (leak):
entries.clear()  // But recordsByKey still holds reference

// After (fixed):
entries.clear()
recordsByKey.delete(key)  // Actually remove the reference

Common Pattern

All three issues stem from the same problem: creating new resources without properly tracking/cleaning up old ones.

Recommendation

  1. Update to the latest version - These fixes are very recent (merged Jan 13-14)
  2. If the issue persists, please export your session to help identify remaining leaks:
    opencode export > session.json
    
  3. The MCP client leak (#8253) is particularly relevant for Copilot users - make sure you have this fix

Related Fixes

  • #8255: TUI timeout leak
  • #8253: MCP client leak
  • #8252: State disposal leak
  • #6435: Model list filter leak
  • #6787: Plugin duplicate initialization
@LIHUA919 commented on GitHub (Jan 18, 2026): Based on my analysis of the recent memory leak fixes, here are the root causes: ## Root Causes ### 1. TUI Footer Timeout Leak (#8255) The footer component creates recursive timeouts but only cleans up the **last one**: ```typescript // Before (leak): let timeout = setTimeout(() => tick(), 10000) onCleanup(() => clearTimeout(timeout)) // Only clears last timeout // After (fixed): const timeouts = [] timeouts.push(setTimeout(() => tick(), 10000)) onCleanup(() => timeouts.forEach(clearTimeout)) // Clears all ``` Hundreds of uncleaned timers accumulate over time. ### 2. MCP Client Not Closed (#8253) When reinitializing MCP clients, the old one was **overwritten without closing**: ```typescript // Before (leak): s.clients[name] = result.mcpClient // Old client still active! // After (fixed): await existingClient?.close() s.clients[name] = result.mcpClient ``` This is especially critical for Copilot users since it uses the MCP protocol. ### 3. State Instance Not Removed from Map (#8252) ```typescript // Before (leak): entries.clear() // But recordsByKey still holds reference // After (fixed): entries.clear() recordsByKey.delete(key) // Actually remove the reference ``` ## Common Pattern All three issues stem from the same problem: **creating new resources without properly tracking/cleaning up old ones**. ## Recommendation 1. **Update to the latest version** - These fixes are very recent (merged Jan 13-14) 2. If the issue persists, please export your session to help identify remaining leaks: ```bash opencode export > session.json ``` 3. The MCP client leak (#8253) is particularly relevant for Copilot users - make sure you have this fix ## Related Fixes - #8255: TUI timeout leak - #8253: MCP client leak - #8252: State disposal leak - #6435: Model list filter leak - #6787: Plugin duplicate initialization
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#6635