Tabs are not released by TabSwitcher #11874

Open
opened 2026-01-31 02:59:53 +00:00 by claunia · 0 comments
Owner

Originally created by @Don-Vito on GitHub (Dec 24, 2020).

Environment

Dev Latest

Steps to reproduce

  1. Measure memory
  2. Create 10 tabs
  3. Open Tab Switcher
  4. Close 10 tabs

Expected behavior

Memory is back to normal

Actual behavior

Memory remains high until Command Palette (action mode) is open.

Same test without opening tab switcher returns memory usage back to normal.

Observations

  1. Heap analysis shows that TerminalTab objects are still alive. Most probably due to CommandPalette still holding a reference to them somehow (I believe this semi-leak exists in 1.5 or earlier, but became painful since introduction of TabPaletteItem, as now we hold a reference to a tab rather than SwitchToTabCommand)
  2. We do not not reset tabs in Palette upon tab removal. This is something we need to fix. But it is insufficient to explain this "leak" - we do call SetTabs on the following invocations of TabSwitcher and yet it does not release the memory
  3. I tried to track when the actual memory release happens, and it looks that it is insufficient to switch to the action mode in the code, we really need to make the palette visible before the memory is released. This led me to the thought that the view is somehow holding the ref-count, although the model has already changed.
  4. I blamed x:Bind not handling PropertyChanged ref-counting correctly (like here: https://github.com/microsoft/microsoft-ui-xaml/issues/934). But removing the INotifyPropertyChanged completely and even converting the bindings to OneTime didn't help. So now I am not sure if this is the right direction
Originally created by @Don-Vito on GitHub (Dec 24, 2020). # Environment ```none Dev Latest ``` # Steps to reproduce 1. Measure memory 2. Create 10 tabs 3. Open Tab Switcher 4. Close 10 tabs # Expected behavior Memory is back to normal # Actual behavior Memory remains high until Command Palette (action mode) is open. Same test without opening tab switcher returns memory usage back to normal. # Observations 1. Heap analysis shows that `TerminalTab` objects are still alive. Most probably due to `CommandPalette` still holding a reference to them somehow (I believe this semi-leak exists in 1.5 or earlier, but became painful since introduction of `TabPaletteItem`, as now we hold a reference to a tab rather than `SwitchToTabCommand`) 2. We do not not reset tabs in Palette upon tab removal. This is something we need to fix. But it is insufficient to explain this "leak" - we do call `SetTabs` on the following invocations of TabSwitcher and yet it does not release the memory 3. I tried to track when the actual memory release happens, and it looks that it is insufficient to switch to the action mode in the code, we really need to make the palette visible before the memory is released. This led me to the thought that the view is somehow holding the ref-count, although the model has already changed. 4. I blamed `x:Bind` not handling `PropertyChanged` ref-counting correctly (like here: https://github.com/microsoft/microsoft-ui-xaml/issues/934). But removing the `INotifyPropertyChanged` completely and even converting the bindings to `OneTime` didn't help. So now I am not sure if this is the right direction
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#11874