Skip to content

Commit 1d11b73

Browse files
michaeljolleyCopilot
authored andcommitted
[CmdPal] Fix memory leak in PerformanceWidgetsPage network band items (#48880)
## Summary Fixes a memory leak in the Performance Monitor dock extension where `GetItems()` created **new** `ListItem` instances for `_networkUpItem` and `_networkDownItem` on every call. ## Problem When the dock subscribes to `ItemsChanged` and calls `GetItems()` to refresh, the band page path allocates 2 new `ListItem` objects each time — the old ones are replaced in the fields but never collected (they remain referenced by the `DockItemViewModel` wrappers until the next refresh cycle). Under normal operation this leaks ~2 objects/second indefinitely. ## Fix Move `_networkUpItem`/`_networkDownItem` creation into the constructor (matching the pattern used by CPU, Memory, GPU, and Battery items). `GetItems()` now returns stable references. The `Updated` event handler already updates their `.Title` properties, which propagates to the UI via `PropChanged` → `CommandItemViewModel.Model_PropChanged`. ## Validation - Build succeeds (`Microsoft.CmdPal.Ext.PerformanceMonitor.csproj`) - Network up/down band items still receive title updates via the existing `Updated` handler - No `RaiseItemsChanged()` needed — `ListItem.Title` setter fires `PropChanged`, which `DockItemViewModel` already observes --------- Co-authored-by: Copilot <[email protected]> (cherry picked from commit 28e0788)
1 parent ab4792a commit 1d11b73

1 file changed

Lines changed: 19 additions & 16 deletions

File tree

src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.PerformanceMonitor/PerformanceWidgetsPage.cs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,25 @@ public PerformanceWidgetsPage(SettingsManager settingsManager, bool isBandPage =
134134
MoreCommands = _networkPage.Commands,
135135
};
136136

137+
if (isBandPage)
138+
{
139+
_networkUpItem = new ListItem(_networkPage)
140+
{
141+
Title = $"{_networkUpSpeed}",
142+
Subtitle = Resources.GetResource("Network_Send_Subtitle"),
143+
Icon = Icons.NetworkUpIcon,
144+
MoreCommands = _networkPage.Commands,
145+
};
146+
147+
_networkDownItem = new ListItem(_networkPage)
148+
{
149+
Title = $"{_networkDownSpeed}",
150+
Subtitle = Resources.GetResource("Network_Receive_Subtitle"),
151+
Icon = Icons.NetworkDownIcon,
152+
MoreCommands = _networkPage.Commands,
153+
};
154+
}
155+
137156
_networkPage.Updated += (s, e) =>
138157
{
139158
_networkItem.Title = _networkPage.GetItemTitle(isBandPage);
@@ -253,22 +272,6 @@ public override IListItem[] GetItems()
253272
}
254273
else
255274
{
256-
_networkUpItem = new ListItem(_networkPage!)
257-
{
258-
Title = $"{_networkUpSpeed}",
259-
Subtitle = Resources.GetResource("Network_Send_Subtitle"),
260-
Icon = Icons.NetworkUpIcon,
261-
MoreCommands = _networkPage!.Commands,
262-
};
263-
264-
_networkDownItem = new ListItem(_networkPage!)
265-
{
266-
Title = $"{_networkDownSpeed}",
267-
Subtitle = Resources.GetResource("Network_Receive_Subtitle"),
268-
Icon = Icons.NetworkDownIcon,
269-
MoreCommands = _networkPage!.Commands,
270-
};
271-
272275
return _batteryItem is not null
273276
? new[] { _cpuItem!, _memoryItem!, _networkUpItem!, _networkDownItem!, _gpuItem!, _batteryItem! }
274277
: new[] { _cpuItem!, _memoryItem!, _networkUpItem!, _networkDownItem!, _gpuItem! };

0 commit comments

Comments
 (0)