Bug 336584 - [Contributions] CommandContributionItem#openDropDownMenu() never release menu manager for drop down menu from workbench menu service.
Summary: [Contributions] CommandContributionItem#openDropDownMenu() never release menu...
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.4   Edit
Hardware: All All
: P3 normal with 9 votes (vote)
Target Milestone: 4.15 M1   Edit
Assignee: Platform UI Triaged CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-02-07 23:44 EST by Jeeeyul Lee CLA
Modified: 2019-12-22 06:54 EST (History)
8 users (show)

See Also:


Attachments
Release menu manager and dispose menu patch against 3.6.2 (1.66 KB, patch)
2011-05-25 23:21 EDT, Kevin Pfarr CLA
no flags Details | Diff
Patch for resource leak using asyncExec (1.74 KB, patch)
2012-01-23 11:04 EST, Stephan Wahlbrink CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jeeeyul Lee CLA 2011-02-07 23:44:42 EST
Build Identifier: eclipse 3.4 to eclipse 3.6

CommandContributionItem#openDropDownMenu() never release menu manager for drop down menu from workbench menu service.

Workbench Menu Service refers (not actually) volatile local MenuManager variable, so it will be zombie object.

If there are another command contribution item in dropdown menu(manager). It can be huge leak, because it retains execution context.
(active part, selection, and so on : some editor or some selection can takes a lot of memory). 

I think it should have to use IMenuListener2 instead of IMenuListener. So it can release when menu will be disappeard.


ps. I tested it Eclipse 3.4 and 3.6, and I confirmed leak through eclipse memory analyzer.

Reproducible: Always

Steps to Reproduce:
1. contribute a command with drop down style, and give a id to place other command on it.
2. place other commands into given menu id.
3. command contribution items which are produced from step2 are never disposed.
Comment 1 Kevin Pfarr CLA 2011-05-25 23:19:50 EDT
The project I'm working on is running into this same issue.  We are using RCP version 3.6.1 and also tested with 3.6.2 on WinXP.  Have not tried the latest 3.7-RC2 version.

Contributed a command with a pulldown style to the view's toolbar.  Then contributed a dynamic item implemented the fill(Menu, int) method to add menu items to the menu.  Images on the menu items needed to be disposed but was unable to rely on adding a dispose listener to the menu.  The menu is disposed when the shell is disposed.  Also could not rely on overriding the dispose() method of ContributionItem, it never gets called.

I've created a patch to dispose the menu manager and menu when menuAboutToHide() method is called.  The patch was created against version 3.6.2.

Also, without disposing the menu, the menu is leaking handles.  Ran a test to open the pulldown menu 10000 times.  It failed to complete with either no more handles exception or unable to create item exception.
Comment 2 Kevin Pfarr CLA 2011-05-25 23:21:40 EDT
Created attachment 196624 [details]
Release menu manager and dispose menu patch against 3.6.2

This patch was created against 3.6.2.
Comment 3 Stephan Wahlbrink CLA 2011-11-29 06:57:13 EST
I think, in the patch the menu is disposed too early. The menu items in the dropdown menu are no longer executed.
Running the release/dispose code inside an Display#asyncExec works for me.
Comment 4 Stephan Wahlbrink CLA 2012-01-23 11:04:06 EST
Created attachment 209921 [details]
Patch for resource leak using asyncExec
Comment 5 Dani Megert CLA 2012-01-23 11:08:04 EST
(In reply to comment #4)
> Created attachment 209921 [details] [diff]
> Patch for resource leak using asyncExec

I didn't look/investigate this bug fully, but often switching to asyncExec can cause other unwanted side-effects. I'd only do this as a last resort.
Comment 6 Paul Webster CLA 2012-01-23 11:29:55 EST
(In reply to comment #4)
> Created attachment 209921 [details]
> Patch for resource leak using asyncExec

Released to master and R3_development.  Thanx Kevin and Stephan.

Dani, while I agree pushing something like that into an asyncExec can lead to unintended consequences, I feel the risk here is low and the usage small.  But if you feel the risk is high please let me know.

PW
Comment 7 Dani Megert CLA 2012-01-24 09:39:32 EST
(In reply to comment #6)
> (In reply to comment #4)
> > Created attachment 209921 [details] [diff]
> > Patch for resource leak using asyncExec
> 
> Released to master and R3_development.  Thanx Kevin and Stephan.
> 
> Dani, while I agree pushing something like that into an asyncExec can lead to
> unintended consequences, I feel the risk here is low and the usage small.  But
> if you feel the risk is high please let me know.

I would have to take a closer look to speak against or for committing this, but since not sure, I wouldn't commit it personally. As an example take a look at bug 244316 which is also in a similar area and the asyncExec causes trouble.
Comment 8 Paul Webster CLA 2012-01-24 11:23:49 EST
(In reply to comment #7)
> 
> I would have to take a closer look to speak against or for committing this, but
> since not sure, I wouldn't commit it personally. As an example take a look at
> bug 244316 which is also in a similar area and the asyncExec causes trouble.

I know.  But in this case, for disposal with a potentially long time before the next dropdown, it follows the same pattern we use in org.eclipse.ui.internal.PopupMenuExtender.menuAboutToHide(IMenuManager).  We need to run cleanup but must wait for the menu selection event to run its course first.

I agree we need to keep an eye out for side effects.

PW
Comment 9 Marc R. Hoffmann CLA 2012-01-24 13:35:12 EST
In our project (Swiss Railroad) this issue also causes a serious memory leak. We have is a multi-window application, where users open and close windows regulary. All menus are build declaratively with commands. Due to the missing dispose() call CommandContributionItem instances stay connected with services like IBindingService, which in turn prevents WorkbenchWindows from getting garbage collected. Here is what MAT shows after a window has been closed:

org.eclipse.ui.internal.WorkbenchWindow
'- fScopingValue org.eclipse.ui.internal.commands.SlaveCommandService
   '- commandService org.eclipse.ui.menus.CommandContributionItem
      '- this$0 org.eclipse.ui.menus.CommandContributionItem$1
         '- [23] java.lang.Object[35]
            '- listeners org.eclipse.core.runtime.ListenerList
               '- listenerList org.eclipse.jface.bindings.BindingManager
                  '- bindingManager org.eclipse.ui.internal.Workbench
Comment 10 Marc R. Hoffmann CLA 2012-01-24 13:55:04 EST
I actually wonder what is the logical difference between toolbar dropdown menus and regular submenus. Both are populated lazily, but with Eclipse 3.7.1 the following differences exist:

Creation: (Sub)Menu contributions are lazily created once per window. Dropdown menu contributions are created every time the dropdown menu is opened.

Dispose: (Sub)Menu contributions are properly disposed by the MenubenchMenuService when a window is closed. Dropdown menu contributions are never disposed.
Comment 11 Daniel Rolka CLA 2013-09-25 05:49:22 EDT
Since the patch for this issue is already present in 4.4 what are we going to do with this bug? Should we close it, do some additional tests or what?

thanks,
Daniel
Comment 12 Paul Webster CLA 2013-10-04 10:16:24 EDT
(In reply to Daniel Rolka from comment #11)
> Since the patch for this issue is already present in 4.4 what are we going
> to do with this bug? Should we close it, do some additional tests or what?

The other thing to do is to look at "Dispose: (Sub)Menu contributions are properly disposed by the MenubenchMenuService when a window is closed. Dropdown menu contributions are never disposed."

And find out why the window dispose works in 3.8 but not in 4.4

PW
Comment 13 Eclipse Genie CLA 2015-03-05 12:09:24 EST
New Gerrit change created: https://git.eclipse.org/r/43253
Comment 15 Rolf Theunissen CLA 2019-12-22 06:54:06 EST
I took a while to review this one. Thanks Stephan for fixing this.