dotnet/winforms

ToolStripMenuItem can lead to memory leaks

Open

#4808 aperta il 18 apr 2021

Vedi su GitHub
 (5 commenti) (1 reazione) (0 assegnatari)C# (922 fork)batch import
:construction: work in progressarea-controls-StripControlshelp wantedtenet-performance

Metriche repository

Star
 (4100 star)
Metriche merge PR
 (Merge medio 14g 22h) (56 PR mergiate in 30 g)

Descrizione

  • .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.
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 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() 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

Guida contributor