Community
Participate
Working Groups
Created attachment 285107 [details] profiler screenshot Reproduction: * Have 100 pom.xml files in the workspace. * Try to scroll from one file to the next and continue. Eclipse shows UI freezes and "application does not respond" quite often. The root cause seems to be that the "base icon" for file types not handled by eclipse is re-computed from scratch every time a tree item in the package explorer changes. With the profiler attached to the IDE, I've collected several seconds of CPU time in org.eclipse.ui.internal.registry.EditorRegistry.getSystemExternalEditorImageDescriptor(String) during 20 seconds of just browsing the package explorer (see attached profiler output). We should probably have some kind of caching for the external editor image instead of requesting it over and over again from the operating system. The UI freezes are all reported similar to this stack trace: Stack Trace at org.eclipse.swt.internal.win32.OS.AssocQueryString(Native Method) at org.eclipse.swt.internal.win32.OS.AssocQueryString(OS.java:1988) at org.eclipse.swt.program.Program.assocQueryString(Program.java:48) at org.eclipse.swt.program.Program.findProgram(Program.java:89) at org.eclipse.ui.internal.registry.EditorRegistry.getSystemExternalEditorImageDescriptor(EditorRegistry.java:1181) at org.eclipse.ui.internal.registry.EditorRegistry.getImageDescriptor(EditorRegistry.java:1373) at org.eclipse.ui.internal.ide.model.WorkbenchFile.getBaseImage(WorkbenchFile.java:67) at org.eclipse.ui.internal.ide.model.WorkbenchResource.getImageDescriptor(WorkbenchResource.java:46) at org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider.getWorkbenchImageDescriptor(JavaElementImageProvider.java:193) at org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider.computeDescriptor(JavaElementImageProvider.java:133) at org.eclipse.jdt.internal.ui.viewsupport.JavaElementImageProvider.getImageLabel(JavaElementImageProvider.java:108) at org.eclipse.jdt.internal.ui.viewsupport.JavaUILabelProvider.getImage(JavaUILabelProvider.java:144) at org.eclipse.jdt.internal.ui.packageview.PackageExplorerLabelProvider.getImage(PackageExplorerLabelProvider.java:139) at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.getImage(DelegatingStyledCellLabelProvider.java:198) at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.getImage(DecoratingStyledCellLabelProvider.java:171) at org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.update(DelegatingStyledCellLabelProvider.java:124) at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider.update(DecoratingStyledCellLabelProvider.java:134) at org.eclipse.jface.viewers.ViewerColumn.refresh(ViewerColumn.java:144) at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:959) at org.eclipse.jface.viewers.AbstractTreeViewer$UpdateItemSafeRunnable.run(AbstractTreeViewer.java:126) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil$$Lambda$121/0x00000008002b2c40.run(Unknown Source) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174) at org.eclipse.jface.viewers.AbstractTreeViewer.doUpdateItem(AbstractTreeViewer.java:1037) at org.eclipse.jdt.internal.ui.viewsupport.ProblemTreeViewer.doUpdateItem(ProblemTreeViewer.java:74) at org.eclipse.jdt.internal.ui.viewsupport.ResourceToItemsMapper.updateItem(ResourceToItemsMapper.java:78) at org.eclipse.jdt.internal.ui.viewsupport.ResourceToItemsMapper.resourceChanged(ResourceToItemsMapper.java:66) at org.eclipse.jdt.internal.ui.viewsupport.ProblemTreeViewer.handleLabelProviderChanged(ProblemTreeViewer.java:192) at org.eclipse.jface.viewers.ContentViewer$1.labelProviderChanged(ContentViewer.java:95) at org.eclipse.jface.viewers.BaseLabelProvider$1.run(BaseLabelProvider.java:75) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.JFaceUtil$$Lambda$121/0x00000008002b2c40.run(Unknown Source) at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:174) at org.eclipse.jface.viewers.BaseLabelProvider.fireLabelProviderChanged(BaseLabelProvider.java:72) at org.eclipse.jface.viewers.DecoratingStyledCellLabelProvider$$Lambda$555/0x0000000800e47840.labelProviderChanged(Unknown Source) at org.eclipse.ui.internal.decorators.DecoratorManager$1.run(DecoratorManager.java:349) at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45) at org.eclipse.ui.internal.decorators.DecoratorManager.fireListener(DecoratorManager.java:346) at org.eclipse.ui.internal.decorators.DecorationScheduler$3.runInUIThread(DecorationScheduler.java:525) at org.eclipse.ui.progress.UIJob.lambda$0(UIJob.java:95) at org.eclipse.ui.progress.UIJob$$Lambda$787/0x0000000801102c40.run(Unknown Source) at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40) at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:185) at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4001) at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3629) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1157) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046) at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155) at org.eclipse.ui.internal.Workbench.lambda$3(Workbench.java:644) at org.eclipse.ui.internal.Workbench$$Lambda$141/0x0000000800344c40.run(Unknown Source) at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338) at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:551) at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:156) at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:152) at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:401) at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255) at java.base@14.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base@14.0.2/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base@14.0.2/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base@14.0.2/java.lang.reflect.Method.invoke(Method.java:564) at app//org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:653) at app//org.eclipse.equinox.launcher.Main.basicRun(Main.java:590) at app//org.eclipse.equinox.launcher.Main.run(Main.java:1461)
Inside org.eclipse.ui.internal.registry.EditorRegistry.getImageDescriptor(String, IContentType) line 1377-1387: // for dynamic UI - comment out the next line // extensionImages.put(key, anImage); Which is the caching you are referring to. This is commented out from the initial contribution of this code, Bug 37668 for Eclipse 3.1. Be sure that we don't loose the 'dynamic UI' (whatever that should be).
I wouldn't want to cache the _overall_ icon lookup, but rather just the external icons. So activating an eclipse plugin with an editor for some file extension would still change the result, but installing a Windows application for the same extension outside eclipse would not change the result anymore (for the running eclipse session). Therefore only the result of getSystemExternalEditorImageDescriptor() would be cached. I've been looking into the profiler a bit more closely. The slowness is caused by SWT using the Windows registry information to look for the associated executable, it's document name, and the icon of the application. All the time is spent in OS.AssocQueryString(), which maps directly to a native Windows function. So I guess there is not much to be optimized in that method itself. (see second screenshot).
Created attachment 285115 [details] AssocQueryString consumes all the time
EGit does that already; see org.eclipse.egit.ui.UIUtils.getEditorImage(). The reason is the same: EditorRegistry.getSystemExternalEditorImageDescriptor() is slow at least on Windows and on Linux. See bug 464891. "dynamic UI" probably refers to changes made in the OS-level default editor associations resulting in showing a new icon as soon as possible (on the next refresh?) in Eclipse.
Re comment 1: The commenting out of the caching and the dynamic UI comment were added in commit dbe9382347d3b20e300466542572c8892e05fb91 on 2004-01-08 "First cut of adding dynamic UIs to the workbench". No bug linked. [1] https://git.eclipse.org/r/plugins/gitiles/platform/eclipse.platform.ui/+/dbe9382347d3b20e300466542572c8892e05fb91%5E%21/#F17
From old mailing list messages, "dynamic UI" could also refer to being able to load and unload UI bundles dynamically without having to restart Eclipse, and still have a sane and usable UI. See e.g. the thread starting at [1]. If that was the intention: * I don't think not caching icons for external editors was correct; and * has unloading a loaded and activated UI bundle with open views or editors ever worked? [1] https://www.eclipse.org/lists/platform-ui-dev/msg01275.html