dotnet / dotnet/winforms

ToolStripMenuItem can lead to memory leaks

Open
#4,808 5 comments 1 reaction 0 assignees View on GitHub
:construction: work in progress area-controls-StripControls help wanted tenet-performance
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
1d 13m
Merged PRs (30d)
85

Description

* .NET Core Version: all up to latest (5.0.5)

* Have you experienced this same bug with .NET Framework?: Yes

**Problem description:**
`ToolStripMenuItem` can lead to memory leaks in some special conditions.

- Menu with submenu.
```
windowsToolStripMenuItem
-> listToolStripMenuItem
```
- Populate and clear submenu in runtime. In fact, only cleaning is important.
```cs
private void WindowsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
for (int i = 0; i < 4; i++)
listToolStripMenuItem.DropDownItems.Add("MenuItem" + i);
}

private void windowsToolStripMenuItem_DropDownClosed(object sender, EventArgs e)
{
while (listToolStripMenuItem.DropDownItems.Count > 0)
listToolStripMenuItem.DropDownItems[listToolStripMenuItem.DropDownItems.Count - 1].Dispose();
}
```
In certain conditions (I think that is - open only main menu and not opening submenu `listToolStripMenuItem`) after closing main menu some of `listToolStripMenuItem` subitems will remain in memory. See video below.
This happens due to [`_displayedItems`](https://github.com/dotnet/winforms/blob/c9287e9ca780cd1828633fd3c6e43a6601896147/src/System.Windows.Forms/src/System/Windows/Forms/ToolStrip.cs#L40) collection still have live references to removed menu items. I think this collection ( and may be `_overflowItems` too ) must be checked on item removal.

https://user-images.githubusercontent.com/17767561/115139643-acf23080-a03b-11eb-9be9-c0e4c2527f38.mp4

*Workaround:*
You can call `listToolStripMenuItem.DropDown.PerformLayout();` after items removal. This lead to call of [`SetDisplayedItems()`](https://github.com/dotnet/winforms/blob/c9287e9ca780cd1828633fd3c6e43a6601896147/src/System.Windows.Forms/src/System/Windows/Forms/ToolStrip.cs#L4561) which will clear `_displayedItems` of removed elements.

**Expected behavior:**
All removed and disposed menu elements must be eligible to GC (have no live references).

**Minimal repro:**
[WinFormsCoreTest_Grid_Menu.zip](https://github.com/dotnet/winforms/files/6330797/WinFormsCoreTest_Grid_Menu.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.