Community
Participate
Working Groups
RenderingViewPane has a hashtable called 'fTabFolderForDebugView'. While the memory view stays open, each successive debug launch adds a IMemoryBlockRetrieval instance to the table. The instance is not removed when the debug session terminates. This is a serious leak. Sure, the table is cleared when the Memory View is closed, but that's not a reasonable cleanup policy. An end-user may do many successive debug sessions without ever closing the Memory view or leaving the Debug perspective. Needlessly keeping a IMemoryBlockRetrieval alive can be very expensive since quite a bit of memory can be tied to it. RenderingViewPane really needs to clean up the map on a IDebugTarget termination. Reproducing this requires CDT and a few breakpoints: 1. Set breakpoints in RenderingViewPane.java and AbstractMemoryViewPane.java in all locations where fTabFolderForDebugView's put, remove and clear methods are called. 2. Launch runtime workbench 3. Switch to debug perspective. 4. Open the Memory view 5. Launch debug session. Note IMemoryBlockRetrieval isntance is added to the table. 6. Terminate debug session. Note the IMemoryBlockRetrieval instance is not removed from the table. On every iteration of 5&6, the table keeps growing.
Will investigate. I do not think there is a good point to clean up the table because IMemoryBlockRetrieval is not really tied to a debug target / ITerminate. We cannot listen for TERMINATE event and determine that the memory block retrieval can be removed.
Natasha, please investigate.
Created attachment 126207 [details] patch with a fix This patch listens for a termination event from the IMemoryBlockRetrieval object and removes it from the map when this happens. It also uses the hashcode for the retrieval objects as the key into the map, rather than the object itself.
Tested out the fix and found this error, when switching between debug sessions: 1) I had two sessions that had renderings created 2) I had 2 other sessions without any renderings 3) Terminate the first two 4) Now switch between the two remaining sessions and I got the following SWT exception. Thread [main] (Suspended (exception SWTException)) owns: RunnableLock (id=124) SWT.error(int, Throwable, String) line: 3862 SWT.error(int, Throwable) line: 3775 SWT.error(int) line: 3746 CTabFolder(Widget).error(int) line: 463 CTabFolder(Widget).checkWidget() line: 336 CTabFolder.addSelectionListener(SelectionListener) line: 491 RenderingViewPane(AbstractMemoryViewPane).setTabFolder(CTabFolder) line: 196 RenderingViewPane(AbstractMemoryViewPane).emptyFolder() line: 250 RenderingViewPane.emptyFolder() line: 957 RenderingViewPane.handleDebugElementSelection(IMemoryViewTab, IAdaptable) line: 641 RenderingViewPane.access$12(RenderingViewPane, IMemoryViewTab, IAdaptable) line: 591 RenderingViewPane$8.runInUIThread(IProgressMonitor) line: 1183 UIJob$1.run() line: 95 RunnableLock.run() line: 35 UISynchronizer(Synchronizer).runAsyncMessages(boolean) line: 133 Display.runAsyncMessages(boolean) line: 3852 Display.readAndDispatch() line: 3473 Workbench.runEventLoop(Window$IExceptionHandler, Display) line: 2388 Workbench.runUI() line: 2352 Workbench.access$4(Workbench) line: 2204 Workbench$5.run() line: 499 Realm.runWithDefault(Realm, Runnable) line: 333 Workbench.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 492 PlatformUI.createAndRunWorkbench(Display, WorkbenchAdvisor) line: 149 IDEApplication.start(IApplicationContext) line: 113 EclipseAppHandle.run(Object) line: 194 EclipseAppLauncher.runApplication(Object) line: 110 EclipseAppLauncher.start(Object) line: 79 EclipseStarter.run(Object) line: 368 EclipseStarter.run(String[], Runnable) line: 179 NativeMethodAccessorImpl.invoke0(Method, Object, Object[]) line: not available [native method] NativeMethodAccessorImpl.invoke(Object, Object[]) line: 45 DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 37 Method.invoke(Object, Object...) line: 599 Main.invokeFramework(String[], URL[]) line: 556 Main.basicRun(String[]) line: 511 Main.run(String[]) line: 1270 Main.main(String[]) line: 1246
The problem is in the AbstractMemoryViewPane#handleDebugEvents method. The when a terminate event is received, we dispose the tab folder that is associated with the memory block retrieval. If the memory view is empty when the debug session is terminated, the tab folder gets disposed. Unfortunately, the empty tab folder is reused in the view, and should never been disposed. Need to add code to check for the empty tab folder before disposing it.
Created attachment 127222 [details] updated patch
Created attachment 127720 [details] updated patch * moved #getHashCode to MemoryViewUtils * code clean up
Applied patch.
Verified.
The committed fix had a compile error in it. I replaced the method in MemoryViewUtils with the following public static Integer getHashCode(Object o) { return new Integer(o.hashCode()); }
Curtis, sorry about that and thanks for fixing it. Not sure why the error did not show up in my workspace. I extracted the code and went back to the previous version, but still did not see an error. What error did you get? I am just curious and wondering if I have a bad workspace set up.
The method valueOf(String) in the type Integer is not applicable for the arguments (int) MemoryViewUtil.java org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/memory line 263 Java Problem Integer.valueOf(int) was added in 1.5. Do you have a 1.4.2 JRE in your workspace? If not Eclipse can't figure out that the code you are using is 1.5 only. API Tooling just added some additional support for this, so you just need a fragment installed not a full JRE, see the API Warnings/Errors preference page, API Use tab, Invalid reference to system libraries option (there is a link to install the different fragments).
It seems to me that using the objects hashcode as a reference-less handle to the object is unsound, as the JVM is explicit in that a VM should *try* to provide unique hashcode for live objects, but that it's not required to. There's a lot of good food for thought on this subject here: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6321873 Perhaps I'm misinterpreting the fix, though...