close
Skip to content

fix: memory leak in pty host service#287025

Merged
dmitrivMS merged 13 commits into
microsoft:mainfrom
SimonSiefke:fix/memory-leak-pty-host
Jun 4, 2026
Merged

fix: memory leak in pty host service#287025
dmitrivMS merged 13 commits into
microsoft:mainfrom
SimonSiefke:fix/memory-leak-pty-host

Conversation

@SimonSiefke

@SimonSiefke SimonSiefke commented Jan 11, 2026

Copy link
Copy Markdown
Contributor

Fixes a memory leak in pty host service.

Details

When starting pty host, various events get registered using this._register:

private _startPtyHost(): [IPtyHostConnection, IPtyService] {
  this._register(proxy.onProcessData(e => this._onProcessData.fire(e)));
  this._register(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
  this._register(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
  this._register(proxy.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
  this._register(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
}

But since there is only one instance of ptyHostService, each time when restarting the pty host, new event listeners get registered, and the number of registered disposables in ptyHostService seems to grow each time.

Change

The change uses a MutableDisposable so that when the pty host is restarted, the previous event listener disposables are disposed.

private readonly ptyHostStore = this._register(new MutableDisposable());

private _startPtyHost(): [IPtyHostConnection, IPtyService, DisposableStore] {
  const store = new DisposableStore();
  store.add(connection.store);

  store.add(proxy.onProcessData(e => this._onProcessData.fire(e)));
  store.add(proxy.onProcessReady(e => this._onProcessReady.fire(e)));
  store.add(proxy.onProcessExit(e => this._onProcessExit.fire(e)));
  store.add(proxy.onDidChangeProperty(e => this._onDidChangeProperty.fire(e)));
  store.add(proxy.onProcessReplay(e => this._onProcessReplay.fire(e)));
  store.add(proxy.onProcessOrphanQuestion(e => this._onProcessOrphanQuestion.fire(e)));
  store.add(proxy.onDidRequestDetach(e => this._onDidRequestDetach.fire(e)));

  /*...*/
  return [connection, proxy, store];
}

async restartPtyHost(): Promise<void> {
	this._disposePtyHost();
	this._isResponsive = true;
	const [_, _2, store] = this._startPtyHost();
	this.ptyHostStore.value = store;
}

Before

When restarting the pty host 37 times, the number of various functions seems to grow by one each time:

pty-restart

After

No more leak is detected.

@vs-code-engineering

vs-code-engineering Bot commented Jan 11, 2026

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

@anthonykim1

Matched files:

  • src/vs/platform/terminal/node/ptyHostService.ts

Copilot AI review requested due to automatic review settings March 13, 2026 09:30

Copilot AI 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.

Pull request overview

Fixes a memory leak in the terminal pty host controller by ensuring event/listener disposables created during pty host startup are cleaned up when the pty host is restarted.

Changes:

  • Introduces a per-pty-host DisposableStore returned from _startPtyHost and tracked via a MutableDisposable.
  • Moves pty-host-scoped event registrations (connection exit, proxy events, logger client, config listener) from this._register to the per-pty-host store.
  • Updates _ensurePtyHost, _startPtyHost, restartPtyHost, and _disposePtyHost to wire disposal through ptyHostStore.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread src/vs/platform/terminal/node/ptyHostService.ts
Comment thread src/vs/platform/terminal/node/ptyHostService.ts Outdated
Comment thread src/vs/platform/terminal/node/ptyHostService.ts
SimonSiefke and others added 2 commits March 13, 2026 10:52
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@Tyriar Tyriar assigned anthonykim1 and unassigned Tyriar Mar 24, 2026
- Rename ptyHostStore to _ptyHostStore for consistency with other private fields
- Simplify _startPtyHost: assign the store inside instead of returning a 3-tuple
- Use _optionalProxy in _disposePtyHost to avoid re-spawning during shutdown
- Reset __connection/__proxy on dispose
- Add regression test that verifies listener counts stay stable across restarts
@dmitrivMS dmitrivMS enabled auto-merge (squash) May 31, 2026 00:33
@dmitrivMS dmitrivMS requested a review from anthonykim1 May 31, 2026 00:33
dmitrivMS
dmitrivMS previously approved these changes May 31, 2026
@dmitrivMS

Copy link
Copy Markdown
Contributor

@SimonSiefke Thank you!

@dmitrivMS dmitrivMS added the perf label May 31, 2026
@dmitrivMS dmitrivMS disabled auto-merge May 31, 2026 12:45
@dmitrivMS dmitrivMS enabled auto-merge (squash) June 1, 2026 06:40
dmitrivMS
dmitrivMS previously approved these changes Jun 1, 2026

Copilot AI 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.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 3

Comment thread src/vs/platform/terminal/test/node/ptyHostService.test.ts Outdated
Comment thread src/vs/platform/terminal/test/node/ptyHostService.test.ts Outdated
Comment thread src/vs/platform/terminal/node/ptyHostService.ts
Co-authored-by: Copilot <copilot@github.com>
auto-merge was automatically disabled June 1, 2026 07:05

Head branch was pushed to by a user without write access

@dmitrivMS dmitrivMS enabled auto-merge (squash) June 1, 2026 07:06
@dmitrivMS dmitrivMS requested a review from Copilot June 1, 2026 07:06

Copilot AI 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.

Copilot's findings

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new

@dmitrivMS dmitrivMS removed the request for review from anthonykim1 June 4, 2026 01:15
@dmitrivMS dmitrivMS merged commit 4335523 into microsoft:main Jun 4, 2026
25 checks passed
@vs-code-engineering vs-code-engineering Bot added this to the 1.124.0 milestone Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants