Skip to content

fix: memory leak in abstract task service#289863

Merged
meganrogge merged 2 commits intomicrosoft:mainfrom
SimonSiefke:fix/memory-leak-abstract-task-service
Jan 23, 2026
Merged

fix: memory leak in abstract task service#289863
meganrogge merged 2 commits intomicrosoft:mainfrom
SimonSiefke:fix/memory-leak-abstract-task-service

Conversation

@SimonSiefke
Copy link
Contributor

Fixes a memory leak in ProblemReporter and AbstractTaskService.

Details

The Emitter in ProblemReporter currently doesn't seem be registered as a Disposable:

class ProblemReporter implements TaskConfig.IProblemReporter {

	private _validationStatus: ValidationStatus;
	private readonly _onDidError: Emitter<string> = new Emitter<string>(); // not registered
	public readonly onDidError: Event<string> = this._onDidError.event;

Therefore one change is registering the Emitter as a Disposable.


Another issue seems to be when calling AbstractTaskService._computeWorkspaceFolderTasks multiple times and using this._register:

private async _computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise<IWorkspaceFolderTaskResult> {
	/* ... */
	const problemReporter = new ProblemReporter(this._outputChannel);
	this._register(problemReporter.onDidError(error => this._showOutput(runSource, undefined, error)));

Since there is only one AbstractTaskService, registering a disposable each time when calling _computeWorkspaceFolderTasks seems make the number of registered disposables grow each time.

By changing it to a DisposableMap the DisposableMap ensures that there is only one problemsReporter disposableStore per workspaceUri. And calling this._workspaceTaskDisposables.set(workspaceFolder.uri, store) automatically disposes the previous registered disposableStore for that workspace uri.

private async _computeWorkspaceFolderTasks(workspaceFolder: IWorkspaceFolder, runSource: TaskRunSource = TaskRunSource.User): Promise<IWorkspaceFolderTaskResult> {
	/* ... */
	const store = new DisposableStore();
	this._workspaceTaskDisposables.set(workspaceFolder.uri, store);
	const problemReporter = store.add(new ProblemReporter(this._outputChannel));
	store.add(problemReporter.onDidError(error => this._showOutput(runSource, undefined, error)));

Before

When configuring a task 37 times, the number of various functions in AbstractTaskService._computeWorkspaceFolderTasks and some other places seems to grow each time:

Untitled

After

When configuring a task 37 times, while the number of some functions still grows, for AbstractTaskService._computeWorkspaceFolderTasks it stays constant now:

task-configure

Copy link
Collaborator

@meganrogge meganrogge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@meganrogge meganrogge enabled auto-merge (squash) January 23, 2026 16:11
@vs-code-engineering vs-code-engineering bot added this to the January 2026 milestone Jan 23, 2026
@meganrogge meganrogge merged commit d50d600 into microsoft:main Jan 23, 2026
17 checks passed
@SimonSiefke SimonSiefke deleted the fix/memory-leak-abstract-task-service branch January 23, 2026 17:32
meganrogge added a commit that referenced this pull request Jan 28, 2026
meganrogge added a commit that referenced this pull request Jan 28, 2026
Revert "fix: memory leak in abstract task service (#289863)"

This reverts commit d50d600.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants