Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 231175 - [Workbench] WorkbenchLabelProvider leaks
Summary: [Workbench] WorkbenchLabelProvider leaks
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: UI (show other bugs)
Version: 3.4   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.4.1   Edit
Assignee: Boris Bokowski CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 251996
  Show dependency tree
 
Reported: 2008-05-08 14:30 EDT by Stefan Xenos CLA
Modified: 2008-10-24 09:05 EDT (History)
1 user (show)

See Also:
Tod_Creasey: review+


Attachments
patch (10.38 KB, patch)
2008-05-08 16:59 EDT, Boris Bokowski CLA
no flags Details | Diff
patch with Stefan's suggestion (1.38 KB, patch)
2008-08-26 22:05 EDT, Boris Bokowski CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Stefan Xenos CLA 2008-05-08 14:30:19 EDT
Every image allocated by WorkbenchLabelProvider is leaked.

1. The images are not disposed when the elements are no longer used by the viewer (fixing this would require a way for the viewer to tell the label provider when each element is no longer needed)

2. The images are not disposed when the label provider itself is disposed.

Item 1 is a would-be-nice issue. Item 2 is more serious. The label provider should be using a LocalResourceManager to allocate its images, and it should dispose the resource manager when the label provider goes away.

6 Images
6 Images at:
java.lang.Error
	at org.eclipse.swt.graphics.Device.new_Object(Device.java:708)
	at org.eclipse.swt.graphics.Image.<init>(Image.java:446)
	at org.eclipse.jface.resource.ImageDescriptor.createImage(ImageDescriptor.java:289)
	at org.eclipse.jface.resource.ImageDescriptor.createImage(ImageDescriptor.java:227)
	at org.eclipse.jface.resource.ImageDescriptor.createImage(ImageDescriptor.java:205)
	at org.eclipse.ui.model.WorkbenchLabelProvider.getImage(WorkbenchLabelProvider.java:157)
	at org.eclipse.jface.viewers.WrappedViewerLabelProvider.getImage(WrappedViewerLabelProvider.java:117)
	at org.eclipse.jface.viewers.WrappedViewerLabelProvider.update(WrappedViewerLabelProvider.java:165)
	at org.eclipse.jface.viewers.ViewerColumn.refresh(ViewerColumn.java:135)
	at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:911)
	at org.eclipse.jface.viewers.AbstractTreeViewer$UpdateItemSafeRunnable.run(AbstractTreeViewer.java:97)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
	at org.eclipse.core.runtime.Platform.run(Platform.java:857)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:46)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:199)
	at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:991)
	at org.eclipse.jface.viewers.StructuredViewer$UpdateItemSafeRunnable.run(StructuredViewer.java:466)
	at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
	at org.eclipse.core.runtime.Platform.run(Platform.java:857)
	at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:46)
	at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:199)
	at org.eclipse.jface.viewers.StructuredViewer.updateItem(StructuredViewer.java:2026)
	at org.eclipse.jface.viewers.AbstractTreeViewer.createTreeItem(AbstractTreeViewer.java:806)
	at org.eclipse.jface.viewers.AbstractTreeViewer$1.run(AbstractTreeViewer.java:781)
	at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
	at org.eclipse.jface.viewers.AbstractTreeViewer.createChildren(AbstractTreeViewer.java:755)
	at org.eclipse.jface.viewers.TreeViewer.createChildren(TreeViewer.java:627)
	at org.eclipse.jface.viewers.AbstractTreeViewer.internalInitializeTree(AbstractTreeViewer.java:1463)
	at org.eclipse.jface.viewers.TreeViewer.internalInitializeTree(TreeViewer.java:816)
	at org.eclipse.jface.viewers.AbstractTreeViewer$5.run(AbstractTreeViewer.java:1446)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1368)
	at org.eclipse.jface.viewers.TreeViewer.preservingSelection(TreeViewer.java:390)
	at org.eclipse.jface.viewers.StructuredViewer.preservingSelection(StructuredViewer.java:1330)
	at org.eclipse.jface.viewers.AbstractTreeViewer.inputChanged(AbstractTreeViewer.java:1435)
	at org.eclipse.ui.dialogs.FilteredTree$NotifyingTreeViewer.inputChanged(FilteredTree.java:797)
	at org.eclipse.jface.viewers.ContentViewer.setInput(ContentViewer.java:251)
	at org.eclipse.jface.viewers.StructuredViewer.setInput(StructuredViewer.java:1606)
	at org.eclipse.ui.internal.dialogs.NewWizardNewPage.createFilteredTree(NewWizardNewPage.java:332)
	at org.eclipse.ui.internal.dialogs.NewWizardNewPage.createControl(NewWizardNewPage.java:254)
	at org.eclipse.ui.internal.dialogs.NewWizardSelectionPage.createControl(NewWizardSelectionPage.java:88)
	at org.eclipse.jface.wizard.Wizard.createPageControls(Wizard.java:170)
	at org.eclipse.jface.wizard.WizardDialog.createPageControls(WizardDialog.java:669)
	at org.eclipse.jface.wizard.WizardDialog.createContents(WizardDialog.java:543)
	at org.eclipse.jface.window.Window.create(Window.java:426)
	at org.eclipse.jface.dialogs.Dialog.create(Dialog.java:1083)
	at org.eclipse.ui.actions.NewProjectAction.run(NewProjectAction.java:108)
	at org.eclipse.jface.action.Action.runWithEvent(Action.java:498)
	at org.eclipse.jface.action.ActionContributionItem.handleWidgetSelection(ActionContributionItem.java:546)
	at org.eclipse.jface.action.ActionContributionItem.access$2(ActionContributionItem.java:490)
	at org.eclipse.jface.action.ActionContributionItem$5.handleEvent(ActionContributionItem.java:402)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1101)
	at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:3319)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2971)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
	at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:169)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:618)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1173)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1148)
Comment 1 Boris Bokowski CLA 2008-05-08 16:59:14 EDT
Created attachment 99380 [details]
patch
Comment 2 Boris Bokowski CLA 2008-05-08 16:59:36 EDT
Tod, do you think we can just do this?
Comment 3 Tod Creasey CLA 2008-05-09 08:59:48 EDT
Absolutely. This is a leftover from the bad old days before Stefans cool ResourceManager stuff.
Comment 4 Boris Bokowski CLA 2008-05-09 09:44:15 EDT
Release to HEAD.
Comment 5 Stefan Xenos CLA 2008-05-09 10:27:56 EDT
Boris: instead of this:

> resourceManager.createImage(descriptor)

I'd suggest using this:

(Image)resourceManager.get(descriptor);

If you don't intend to use reference counting, then the former has the possibility of integer overflow in the extreme case where you call it billions of times, but the latter is always safe.
Comment 6 Boris Bokowski CLA 2008-05-09 10:53:16 EDT
Stefan, don't I have to do a more complicated dance then, like this?

result = (Image)resourceManager.get(descriptor);
if (result==null) result = resourceManager.createImage(descriptor);

I think I've seen a bug filed by Andre asking for this to be supported as just one method call but I can't find it right now.
Comment 7 Stefan Xenos CLA 2008-05-10 10:46:39 EDT
> I think I've seen a bug filed by Andre asking for this to be supported as 
> just one method call but I can't find it right now.

No, you're thinking of resourceManager.find. The get method was the one-method-call version I wrote to fix Andre's bug.
Comment 8 Boris Bokowski CLA 2008-05-30 22:25:35 EDT
Reopening for a better fix without potential overflow in 3.4.1.
Comment 9 Boris Bokowski CLA 2008-08-26 22:05:53 EDT
Created attachment 111018 [details]
patch with Stefan's suggestion
Comment 10 Boris Bokowski CLA 2008-08-26 22:06:47 EDT
Released to R3_4_maintenance