fix: memory leak in tunnel view#287142
Merged
alexr00 merged 9 commits intomicrosoft:mainfrom Feb 13, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses memory leaks in the Ports (tunnel) view table by aligning the ActionBarRenderer lifecycle with the table renderer model (template/element disposables), rather than relying on this._register() from a long-lived Disposable base class.
Changes:
- Refactors
ActionBarRendererto no longer extendDisposable, and instead manage disposables viatemplateDisposablesandelementDisposables. - Ensures per-element resources (e.g., menus, buttons, input handlers) are disposed by clearing
elementDisposableson each render and indisposeElement. - Simplifies template disposal by disposing a single
templateDisposablesstore indisposeTemplate.
Comments suppressed due to low confidence (2)
src/vs/workbench/contrib/remote/browser/tunnelView.ts:370
- New statements in
renderTemplateare missing semicolons (and the surrounding file consistently uses them). Please add semicolons here (and in the other newly added lines) to match the repo style and avoid ASI-related lint/format issues.
const templateDisposables = new DisposableStore()
const elementDisposables = new DisposableStore();
templateDisposables.add(elementDisposables)
const label = templateDisposables.add(new IconLabel(cell,
src/vs/workbench/contrib/remote/browser/tunnelView.ts:518
renderInputBoxcreates a newInputBoxand appends it to the cell container each time edit mode is entered. DisposingInputBoxdoes not remove its.elementfrom the DOM (it only disposes listeners), so repeated toggling can accumulate hidden input DOM nodes in the row template. Consider either reusing a singleInputBoxstored ontemplateDataor explicitly removing/clearing the createdinputBox.elementwhen finishing/disposing.
const { container } = templateData
container.style.paddingLeft = '5px';
const value = editableData.startingValue || '';
const inputBox = new InputBox(container, this.contextViewService, {
ariaLabel: nls.localize('remote.tunnelsView.input', "Press Enter to confirm or Escape to cancel."),
validationOptions: {
validation: (value) => {
const message = editableData.validationMessage(value);
if (!message) {
return null;
}
return {
content: message.content,
formatContent: true,
type: message.severity === Severity.Error ? MessageType.ERROR : MessageType.INFO
};
}
},
placeholder: editableData.placeholder || '',
inputBoxStyles: defaultInputBoxStyles
});
Tyriar
approved these changes
Feb 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes some memory leaks in tunnel view.
Details
Table renderers and list renderers are special since they don't use
this._registerfor registering disposables but insteadtemplateDisposablesandelementDisposables.Change
Changes
ActionBarRendererto not be a disposable anymore since TableRenderers and ListRenderers are (almost?) always not Disposables.Instead, the code now uses
elementDisposablesandtemplateDisposablesto register the items.Before
When opening the ports tunnel view and toggling the input 37 times, the number of functions seems to grow each time in
ActionBarRenderer.renderButtonand some other places:After
No more leak is detected.