Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] Mainline Patch for PR 61965/63990 (scalability)

Folks,

This patch addresses the scalability issues discussed (with the test 
driver) in PR 61965 and also happens to fix the NPE in PR 63990.  This
patch hits a fair number of files in order to properly dispose of 
listeners and resources which were limiting the C/C++ Editor to only
opening and closing a file repeatedly ~500 times before running out
of memory.  JUnit tests run clean, but component owners should check
the update since the following classes were touched: 

CPluginImages,MouseClickListener,CEditorErrorTickUpdater,
CEditorActionContribution, CContentOutlinePage, CEditor, 
SelectionSearchGroup, MemberFilterActionGroup, RefactoringActionGroup

An incidental upside is that we also use significantly less memory 
(~5-10M) on a single editor isntance opening now then we did before.

For the ChangeLog:
- Properly detach listeners and dispose of components to address 
  resource and memory leaks from CEditor stress test (PR 61965)

Index: src/org/eclipse/cdt/internal/ui/CPluginImages.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/CPluginImages.java,v
retrieving revision 1.42
diff -u -r1.42 CPluginImages.java
--- src/org/eclipse/cdt/internal/ui/CPluginImages.java	17 May 2004 15:50:32 -0000	1.42
+++ src/org/eclipse/cdt/internal/ui/CPluginImages.java	25 May 2004 21:35:51 -0000
@@ -282,10 +282,18 @@
 	 * Sets all available image descriptors for the given action.
 	 */	
 	public static void setImageDescriptors(IAction action, String type, String relPath) {
-		relPath= relPath.substring(NAME_PREFIX_LENGTH);
-		action.setDisabledImageDescriptor(create(T + "d" + type, relPath)); //$NON-NLS-1$
-		action.setHoverImageDescriptor(create(T + "c" + type, relPath)); //$NON-NLS-1$
-		action.setImageDescriptor(create(T + "e" + type, relPath)); //$NON-NLS-1$
+//Use the managed version so that we ensure that there is no resource handle leaks
+//Let the widget itself manage the disabled/hover attribution.  This was a huge leak
+//		relPath= relPath.substring(NAME_PREFIX_LENGTH);
+//		action.setDisabledImageDescriptor(create(T + "d" + type, relPath)); //$NON-NLS-1$
+//		action.setHoverImageDescriptor(create(T + "c" + type, relPath)); //$NON-NLS-1$
+//		action.setImageDescriptor(create(T + "e" + type, relPath)); //$NON-NLS-1$
+
+		ImageDescriptor desc = getImageRegistry().getDescriptor(relPath);
+		if(desc == null) {
+			desc = createManaged(T + "e" + type, relPath);
+		}	
+		action.setImageDescriptor(desc);
 	}
 	
 	/**
Index: src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java,v
retrieving revision 1.24
diff -u -r1.24 CContentOutlinePage.java
--- src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java	5 May 2004 16:21:22 -0000	1.24
+++ src/org/eclipse/cdt/internal/ui/editor/CContentOutlinePage.java	25 May 2004 21:35:55 -0000
@@ -137,9 +137,6 @@
 		}
 		
 		fRefactoringActionGroup.fillContextMenu(menu);
-		
-		
-		
 	}
 	
 	/**
@@ -147,7 +144,6 @@
 	 */
 	public void createControl(Composite parent) {
 		treeViewer = new ProblemTreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
-		treeViewer.addSelectionChangedListener(this);
 		
 		treeViewer.setContentProvider(new CElementContentProvider(true, true));
 		treeViewer.setLabelProvider(new StandardCElementLabelProvider());
@@ -166,30 +162,55 @@
 		Control control= treeViewer.getControl();
 		Menu menu= manager.createContextMenu(control);
 		control.setMenu(menu);
-
 		
 		// register global actions
 		IPageSite site= getSite();
 		site.registerContextMenu(fContextMenuId, manager, treeViewer);
 		site.setSelectionProvider(treeViewer);
+		
 		IActionBars bars= site.getActionBars();		
 		bars.setGlobalActionHandler(ICEditorActionDefinitionIds.TOGGLE_PRESENTATION, fTogglePresentation);
-		
-		registerToolbarActions();
 
 		fSelectionSearchGroup = new SelectionSearchGroup(this);
 		fRefactoringActionGroup = new RefactoringActionGroup(this, null);
 		
 		treeViewer.setInput(fInput);
-
 	}
 	
 	public void dispose() {
 		CUIPlugin.getDefault().getProblemMarkerManager().removeListener(treeViewer);
+		
+		if (treeViewer != null) {
+			treeViewer.removeSelectionChangedListener(this);
+		}
+		
+		if (fTogglePresentation != null) {
+			fTogglePresentation.setEditor(null);
+			fTogglePresentation= null;
+		}
+		
 		if (fMemberFilterActionGroup != null) {
 			fMemberFilterActionGroup.dispose();
 			fMemberFilterActionGroup= null;
-		}		
+		}
+		
+		if (fRefactoringActionGroup != null) {
+			fRefactoringActionGroup.dispose();
+			fRefactoringActionGroup= null;
+		}
+		
+		if (fSelectionSearchGroup != null) {
+			fSelectionSearchGroup.dispose();
+			fSelectionSearchGroup= null;
+		}
+				
+		if (selectionChangedListeners != null) {
+			selectionChangedListeners.clear();
+			selectionChangedListeners= null;
+		}
+		
+		fInput= null;
+		
 		super.dispose();
 	}
 
@@ -201,6 +222,9 @@
 		
 		LexicalSortingAction action= new LexicalSortingAction(getTreeViewer());
 		toolBarManager.add(action);
+
+		fMemberFilterActionGroup= new MemberFilterActionGroup(treeViewer, "COutlineViewer"); //$NON-NLS-1$
+		fMemberFilterActionGroup.fillActionBars(actionBars);
 	}
 
 	/* (non-Javadoc)
@@ -276,8 +300,8 @@
 		if (treeViewer != null) 
 			treeViewer.setSelection(selection);
 	}
-
 	/**
+	 * Set the current input to the content provider.  
 	 * @param unit
 	 */
 	public void setInput(ITranslationUnit unit) {
@@ -288,16 +312,5 @@
 		contentUpdated();		
 	}
 
-	private void registerToolbarActions() {
-		
-		IToolBarManager toolBarManager= getSite().getActionBars().getToolBarManager();
-		if (toolBarManager != null) {	
-			//toolBarManager.add(new ClassOnlyAction());		
-			//toolBarManager.add(new LexicalSortingAction());
-			
-			fMemberFilterActionGroup= new MemberFilterActionGroup(treeViewer, "COutlineViewer"); //$NON-NLS-1$
-			fMemberFilterActionGroup.contributeToToolBar(toolBarManager);
-		}
-	}
 
 }
Index: src/org/eclipse/cdt/internal/ui/editor/CEditor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditor.java,v
retrieving revision 1.59
diff -u -r1.59 CEditor.java
--- src/org/eclipse/cdt/internal/ui/editor/CEditor.java	21 May 2004 05:43:13 -0000	1.59
+++ src/org/eclipse/cdt/internal/ui/editor/CEditor.java	25 May 2004 21:35:56 -0000
@@ -76,13 +76,14 @@
 import org.eclipse.ui.actions.ActionGroup;
 import org.eclipse.ui.editors.text.EditorsUI;
 import org.eclipse.ui.editors.text.TextEditor;
+import org.eclipse.ui.ide.IDE;
 import org.eclipse.ui.part.EditorActionBarContributor;
 import org.eclipse.ui.part.IShowInSource;
 import org.eclipse.ui.part.ShowInContext;
+import org.eclipse.ui.texteditor.AbstractTextEditor;
 import org.eclipse.ui.texteditor.AnnotationPreference;
 import org.eclipse.ui.texteditor.ChainedPreferenceStore;
 import org.eclipse.ui.texteditor.ContentAssistAction;
-import org.eclipse.ui.texteditor.DefaultRangeIndicator;
 import org.eclipse.ui.texteditor.IEditorStatusLine;
 import org.eclipse.ui.texteditor.ITextEditorActionConstants;
 import org.eclipse.ui.texteditor.MarkerAnnotation;
@@ -103,12 +104,14 @@
 	protected CContentOutlinePage fOutlinePage;
 	
 	/** Search actions **/
-	
 	private ActionGroup fSelectionSearchGroup;
 	private ActionGroup fRefactoringActionGroup;
+	private ShowInCViewAction fShowInCViewAction;
 	
+	/** Activity Listeners **/
 	protected ISelectionChangedListener fStatusLineClearer;
-    
+    protected ISelectionChangedListener fSelectionUpdateListener;
+	
     /** The property change listener */
     private PropertyChangeListener fPropertyChangeListener = new PropertyChangeListener();
     /** The mouse listener */
@@ -158,29 +161,30 @@
 	 */
 	public CEditor() {
 		super();
+	}
+
+	/**
+	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
+	 */
+	protected void initializeEditor() {
+		//@@@ We should be able to get this from our parent
 		fAnnotationPreferences = new MarkerAnnotationPreferences();
+
 		CTextTools textTools = CUIPlugin.getDefault().getTextTools();
 		setSourceViewerConfiguration(new CSourceViewerConfiguration(textTools, this));
 		setDocumentProvider(CUIPlugin.getDefault().getDocumentProvider());
-		setRangeIndicator(new DefaultRangeIndicator());
-		//setPreferenceStore(CUIPlugin.getDefault().getPreferenceStore());
-
+	
 		setEditorContextMenuId("#CEditorContext"); //$NON-NLS-1$
 		setRulerContextMenuId("#CEditorRulerContext"); //$NON-NLS-1$
 		setOutlinerContextMenuId("#CEditorOutlinerContext"); //$NON-NLS-1$
 
-		fCEditorErrorTickUpdater = new CEditorErrorTickUpdater(this);          
-	}
-
-	/*
-	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
-	 */
-	protected void initializeEditor() {
 		IPreferenceStore[] stores = new IPreferenceStore[2];
 		stores[0] = CUIPlugin.getDefault().getPreferenceStore();
 		stores[1] = EditorsUI.getPreferenceStore();
 		IPreferenceStore store = new ChainedPreferenceStore(stores);
 		setPreferenceStore(store);
+
+		fCEditorErrorTickUpdater = new CEditorErrorTickUpdater(this);          
 	}
 
 	/**
@@ -188,7 +192,9 @@
 	 */
 	protected void doSetInput(IEditorInput input) throws CoreException {
 		super.doSetInput(input);
-		fCEditorErrorTickUpdater.setAnnotationModel(getDocumentProvider().getAnnotationModel(input));
+		if (fCEditorErrorTickUpdater != null) {
+			fCEditorErrorTickUpdater.setAnnotationModel(getDocumentProvider().getAnnotationModel(input));
+		}
 		setOutlinePageInput(fOutlinePage, input);
 	}
 
@@ -298,16 +304,6 @@
 	}
 
 	/**
-	 * 
-	 */
-	private void disableBrowserLikeLinks() {
-		if (fMouseListener != null) {
-			fMouseListener.uninstall();
-			fMouseListener= null;
-		}
-	}
-
-	/**
 	 * @see ISelectionChangedListener#selectionChanged
 	 */
 	public void selectionChanged(SelectionChangedEvent event) {
@@ -437,18 +433,60 @@
 
 		if (fCEditorErrorTickUpdater != null) {
 			fCEditorErrorTickUpdater.setAnnotationModel(null);
+			fCEditorErrorTickUpdater.dispose();
 			fCEditorErrorTickUpdater = null;
 		}
-		if (fBracketMatcher != null) {
-			fBracketMatcher.dispose();
-			fBracketMatcher = null;
-		}
+		
         if (fPropertyChangeListener != null) {
 			Preferences preferences = CCorePlugin.getDefault().getPluginPreferences();
 			preferences.removePropertyChangeListener(fPropertyChangeListener);			
 			IPreferenceStore preferenceStore = getPreferenceStore();
 			preferenceStore.removePropertyChangeListener(fPropertyChangeListener);
+			fPropertyChangeListener = null;
+        
+		}
+        
+        if (fSelectionUpdateListener != null) {
+			getSelectionProvider().addSelectionChangedListener(fSelectionUpdateListener);
+			fSelectionUpdateListener = null;
         }
+        
+       	if (fStatusLineClearer != null) {
+			ISelectionProvider provider = getSelectionProvider();
+       		provider.removeSelectionChangedListener(fStatusLineClearer);
+			fStatusLineClearer = null;
+		}
+        
+        if (fBracketMatcher != null) {
+			fBracketMatcher.dispose();
+			fBracketMatcher = null;
+		}
+		
+		if (fOutlinePage != null) {
+			fOutlinePage.dispose();
+			fOutlinePage = null;
+		}
+		
+		if (fShowInCViewAction != null) {
+			fShowInCViewAction.dispose();
+			fShowInCViewAction = null;
+		}
+		
+		if (fRefactoringActionGroup != null) {
+			fRefactoringActionGroup.dispose();
+			fRefactoringActionGroup = null;
+		}
+		
+		if (fSelectionSearchGroup != null) {
+			fSelectionSearchGroup.dispose();
+			fSelectionSearchGroup = null;
+		}
+		
+		stopTabConversion();
+		disableBrowserLikeLinks();
+		
+		fAnnotationPreferences = null;
+       
 		super.dispose();
 	}
 
@@ -517,11 +555,12 @@
 		action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_DECL);
 		setAction("OpenDeclarations", action); //$NON-NLS-1$
 
-		action = new ShowInCViewAction(this);
+		fShowInCViewAction = new ShowInCViewAction(this);
+		action = fShowInCViewAction;
 		action.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_CVIEW);
 		setAction("ShowInCView", action); //$NON-NLS-1$
 		
-		//Selection Search group
+		//Assorted action groupings
 		fSelectionSearchGroup = new SelectionSearchGroup(this);
 		fRefactoringActionGroup = new RefactoringActionGroup(this, null);
 		
@@ -574,7 +613,7 @@
 	 */
 	public void createPartControl(Composite parent) {
 		super.createPartControl(parent);
-		ISelectionChangedListener sListener = new ISelectionChangedListener() {
+		fSelectionUpdateListener = new ISelectionChangedListener() {
 			private Runnable fRunnable = new Runnable() {
 				public void run() {
 					updateStatusField(CTextEditorActionConstants.STATUS_CURSOR_POS);
@@ -589,7 +628,7 @@
 				fDisplay.asyncExec(fRunnable);
 			}
 		};
-		getSelectionProvider().addSelectionChangedListener(sListener);
+		getSelectionProvider().addSelectionChangedListener(fSelectionUpdateListener);
 
 		if (isTabConversionEnabled())
 			startTabConversion();
@@ -660,8 +699,7 @@
 
 		if (nextError != null) {
 
-			
-			gotoMarker(nextError);
+			IDE.gotoMarker(this, nextError);
 
 			IWorkbenchPage page = getSite().getPage();
 
@@ -875,10 +913,12 @@
 		IWorkingCopyManager mgr = CUIPlugin.getDefault().getWorkingCopyManager();
 		ITranslationUnit unit = mgr.getWorkingCopy(getEditorInput());
 		String fileType = (unit != null && unit.isCXXLanguage()) ? LANGUAGE_CPP : LANGUAGE_C;
-		
+
 		fAnnotationAccess = createAnnotationAccess();
+		
+		//TODO: TF NOTE: This can be greatly cleaned up using the parent createOverviewRuler method
+		//It will also totally get rid of the need for the fAnnotationPreferences in this object
 		ISharedTextColors sharedColors = CUIPlugin.getDefault().getSharedTextColors();
-
 		fOverviewRuler = new OverviewRuler(fAnnotationAccess, VERTICAL_RULER_WIDTH, sharedColors);
 		Iterator e = fAnnotationPreferences.getAnnotationPreferences().iterator();
 		while (e.hasNext()) {
@@ -900,6 +940,8 @@
 		
 		configureSourceViewerDecorationSupport(fSourceViewerDecorationSupport);
 		
+		//TODO: TF NOTE: Add the bracket matching back in here!
+		
 		return sourceViewer;
 	}
 
@@ -956,9 +998,8 @@
 
     }  
 
-    //Links
     /**
-     * Enables browser like links.
+     * Enables browser like links, requires disable to clean up 
      */
     private void enableBrowserLikeLinks() {
     	if (fMouseListener == null) {
@@ -968,20 +1009,31 @@
     	}
     }
     
+   	/**
+	 * Disable browser like links, clean up resources  
+	 */
+	private void disableBrowserLikeLinks() {
+		if (fMouseListener != null) {
+			fMouseListener.uninstall();
+			fMouseListener= null;
+		}
+	}
+    
     /**
-	 * @return
+     * Determine if the hyperlink capability is enabled
+	 * @return boolean indicating if hyperlinking is enabled
 	 */
 	private boolean hyperLinkEnabled() {
 		IPreferenceStore store= getPreferenceStore();
-		boolean Value = store.getBoolean(HYPERLINK_ENABLED);
-		return Value;
+		return store.getBoolean(HYPERLINK_ENABLED);
  	}
      
 	/* (non-Javadoc)
 	 * @see org.eclipse.cdt.internal.ui.editor.IReconcilingParticipant#reconciled()
 	 */
 	public void reconciled(boolean somethingHasChanged) {
-		if(somethingHasChanged)
+		if(somethingHasChanged && fOutlinePage != null) {
 			fOutlinePage.contentUpdated();
+		}
 	}
 }
Index: src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java,v
retrieving revision 1.13
diff -u -r1.13 CEditorActionContributor.java
--- src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java	2 May 2004 03:33:21 -0000	1.13
+++ src/org/eclipse/cdt/internal/ui/editor/CEditorActionContributor.java	25 May 2004 21:35:56 -0000
@@ -210,4 +210,11 @@
 		super.contributeToStatusLine(statusLineManager);
 	}
 
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.IEditorActionBarContributor#dispose()
+	 */
+	public void dispose() {
+		setActiveEditor(null);
+		super.dispose();
+	}
 }
Index: src/org/eclipse/cdt/internal/ui/editor/CEditorErrorTickUpdater.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorErrorTickUpdater.java,v
retrieving revision 1.4
diff -u -r1.4 CEditorErrorTickUpdater.java
--- src/org/eclipse/cdt/internal/ui/editor/CEditorErrorTickUpdater.java	2 Feb 2004 17:06:59 -0000	1.4
+++ src/org/eclipse/cdt/internal/ui/editor/CEditorErrorTickUpdater.java	25 May 2004 21:35:56 -0000
@@ -88,6 +88,13 @@
 		}
 	}	
 	
+	public void dispose() {
+		if (fLabelProvider != null) {
+			fLabelProvider.dispose();
+			fLabelProvider= null;
+		}
+		fAnnotationModel= null;
+	}
 }
 
 
Index: src/org/eclipse/cdt/internal/ui/editor/MouseClickListener.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/MouseClickListener.java,v
retrieving revision 1.3
diff -u -r1.3 MouseClickListener.java
--- src/org/eclipse/cdt/internal/ui/editor/MouseClickListener.java	19 May 2004 06:12:07 -0000	1.3
+++ src/org/eclipse/cdt/internal/ui/editor/MouseClickListener.java	25 May 2004 21:35:56 -0000
@@ -201,18 +201,18 @@
 			fCursor= null;
 		}
 		
-		ISourceViewer sourceViewer= fViewer;
-		if (sourceViewer == null)
-			return;
-		
 		IPreferenceStore preferenceStore= fPrefStore;
 		if (preferenceStore != null)
 			preferenceStore.removePropertyChangeListener(this);
-		
+
+		ISourceViewer sourceViewer= fViewer;
+		if (sourceViewer == null)
+			return;
+
 		StyledText text= sourceViewer.getTextWidget();
 		if (text == null || text.isDisposed())
 			return;
-		
+						
 		text.removeKeyListener(this);
 		text.removeMouseListener(this);
 		text.removeMouseMoveListener(this);
Index: src/org/eclipse/cdt/internal/ui/search/actions/SelectionSearchGroup.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/search/actions/SelectionSearchGroup.java,v
retrieving revision 1.2
diff -u -r1.2 SelectionSearchGroup.java
--- src/org/eclipse/cdt/internal/ui/search/actions/SelectionSearchGroup.java	5 May 2004 16:21:22 -0000	1.2
+++ src/org/eclipse/cdt/internal/ui/search/actions/SelectionSearchGroup.java	25 May 2004 21:35:59 -0000
@@ -90,4 +90,23 @@
 		}
 		return null;
 	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.actions.ActionGroup#dispose()
+	 */
+	public void dispose() {
+		if (fDeclarationsSearchGroup != null) {
+			fDeclarationsSearchGroup.dispose();
+			fDeclarationsSearchGroup= null;
+		}
+		
+		if (fRefSearchGroup != null) {
+			fRefSearchGroup.dispose();
+			fRefSearchGroup= null;
+		}
+		
+		fEditor= null;
+		
+		super.dispose();
+	}
 }
Index: src/org/eclipse/cdt/ui/actions/MemberFilterActionGroup.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/MemberFilterActionGroup.java,v
retrieving revision 1.2
diff -u -r1.2 MemberFilterActionGroup.java
--- src/org/eclipse/cdt/ui/actions/MemberFilterActionGroup.java	2 May 2004 03:33:21 -0000	1.2
+++ src/org/eclipse/cdt/ui/actions/MemberFilterActionGroup.java	25 May 2004 21:36:00 -0000
@@ -260,6 +260,10 @@
 	 * @see ActionGroup#dispose()
 	 */
 	public void dispose() {
+		fFilterActions= null;
+		fFilter= null;
+		fViewer= null;
+		
 		super.dispose();
 	}
 
Index: src/org/eclipse/cdt/ui/actions/RefactoringActionGroup.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/actions/RefactoringActionGroup.java,v
retrieving revision 1.3
diff -u -r1.3 RefactoringActionGroup.java
--- src/org/eclipse/cdt/ui/actions/RefactoringActionGroup.java	23 Apr 2004 18:11:55 -0000	1.3
+++ src/org/eclipse/cdt/ui/actions/RefactoringActionGroup.java	25 May 2004 21:36:00 -0000
@@ -102,9 +102,9 @@
 	private CEditor fEditor;
 	private String fGroupName= IContextMenuConstants.GROUP_REORGANIZE;
 
-	private SelectionDispatchAction fRenameAction;	
-	private SelectionDispatchAction fRedoAction;	
-	private SelectionDispatchAction fUndoAction;	
+	private RenameRefactoringAction fRenameAction;	
+	private RedoRefactoringAction 	fRedoAction;	
+	private UndoRefactoringAction 	fUndoAction;	
 	private List fEditorActions;
 	
 	private static class NoActionAvailable extends Action {
@@ -148,8 +148,8 @@
 		
 		ISelectionProvider provider= editor.getSelectionProvider();
 		ISelection selection= provider.getSelection();
-		fEditorActions= new ArrayList();
-		
+		fEditorActions= new ArrayList(3);
+
 		fRenameAction= new RenameRefactoringAction(editor);
 		fRenameAction.update(selection);
 		editor.setAction("RenameElement", fRenameAction); //$NON-NLS-1$
@@ -164,7 +164,7 @@
 		fRedoAction.update(selection);
 		editor.setAction("RedoAction", fRedoAction); //$NON-NLS-1$
 		fEditorActions.add(fRedoAction);
-}
+	}
 
 	public RefactoringActionGroup(IWorkbenchSite site, String groupName) {
 		fSite= site;
@@ -212,15 +212,34 @@
 	 */
 	public void dispose() {
 		ISelectionProvider provider= fSite.getSelectionProvider();
-		disposeAction(fRenameAction, provider);
-		disposeAction(fUndoAction, provider);
-		disposeAction(fRedoAction, provider);
+		
+		if (fRenameAction != null) {
+			disposeAction(fRenameAction, provider);
+			fRenameAction= null;
+		}
+		
+		if (fUndoAction != null) {
+			disposeAction(fUndoAction, provider);
+			fUndoAction.dispose();
+			fUndoAction= null;
+		}
+		
+		if (fRedoAction != null) {
+			disposeAction(fRedoAction, provider);
+			fRedoAction.dispose();
+			fRedoAction= null;
+		}
+		
+		if (fEditorActions != null) {
+			fEditorActions.clear();
+			fEditorActions= null;
+		}
+		
 		super.dispose();
 	}
 	
 	private void disposeAction(ISelectionChangedListener action, ISelectionProvider provider) {
-		if (action != null)
-			provider.removeSelectionChangedListener(action);
+		provider.removeSelectionChangedListener(action);
 	}
 	
 	private void addRefactorSubmenu(IMenuManager menu) {

Back to the top