Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 375690 - Memory leaks: deleted projects stay in memory forever on the server as well as on the client
Summary: Memory leaks: deleted projects stay in memory forever on the server as well a...
Status: CLOSED FIXED
Alias: None
Product: EMFStore
Classification: Modeling
Component: Common (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 0.9.0   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-03-30 04:29 EDT by Dmitry Litvinov CLA
Modified: 2012-05-07 10:17 EDT (History)
1 user (show)

See Also:


Attachments
A patch, removing memory leaks (12.97 KB, patch)
2012-03-30 04:31 EDT, Dmitry Litvinov CLA
eclipse: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitry Litvinov CLA 2012-03-30 04:29:46 EDT
Build Identifier: 

Deleted ProjectSpaces and Projects stay in memory forever as well as all included model elements. The problem is actual for both server and client.
The attached patch solves the problem. For some reason, it cannot be applied with (my) git, works without problems in Eclipse. It should be applied on the workspace root, with option "Ignoring leading path name segments" set to 1
To archieve the result the following actions are performed.
1. All resources are deleted after deletion of ProjectSpace and Project.
2. OperationRecorder.emfStoreCommandStack on the client is cleared
3. WorkspaceManager.observerBus on the client is cleared
4. ECrossReferenceAdapter on the client is extended to delete all resources of a deleted project from map unloadedResource

Reproducible: Always

Steps to Reproduce:
Project stays in memory after deletion on the server
1. Import a project from a file.
2. Share it to the server.
3. Delete the project from the server
Server uses more memory than it used before.

Project stays in memory after deletion on the client
1. Checkout a project from the server.
2. Delete the project from the workspace.
Client uses more memory than it used before.
Comment 1 Dmitry Litvinov CLA 2012-03-30 04:31:33 EDT
Created attachment 213376 [details]
A patch, removing memory leaks
Comment 2 Edgar Mueller CLA 2012-04-12 08:07:28 EDT
Patch has been applied and tested with slight modifications.  Thanks for the contribution.
Comment 3 Dmitry Litvinov CLA 2012-04-27 04:52:57 EDT
The problem is reproduced on the client.
Line
WorkspaceManager.getObserverBus().unregister(this, LoginObserver.class);
has to be in the method ProjectSpaceBase.delete() as it was proposed in the patch, or method 
ObserverBus.unregister(IObsever) has to be fixed, because invocation
WorkspaceManager.getObserverBus().unregister(this) doesn't remove ProjectSpace from the ObserverBus. Method unregister(IObsever observer) supposes that the ProjectSpace is registered for one of interfaces, implemented by the observer
Comment 4 Edgar Mueller CLA 2012-04-27 08:54:02 EDT
Ok, well I'll change the line to WorkspaceManager.getObserverBus().unregister(this, LoginObserver.class) then.  
I propose that you create a new bug report, since in my understanding ObserverBus#unregister is not working as expected.  Please describe the issue there.  I'll close this bug report as soon as the mentioned line has been changed and pushed.
Comment 5 Dmitry Litvinov CLA 2012-04-27 09:43:41 EDT
No, as far as I have understood, ObserverBus#unregister is expected to work exactly so. And the bug report is not required.
/**
 * Unregisters an observer for all observer interfaces implemented by the object or its super classes.
 * 
 * @param observer observer object
 */
public void unregister(IObserver observer) {
...

/**
 * Registers an observer for all observer interfaces implemented by the object or its super classes.
 * 
 * @param observer observer object
 */
public void register(IObserver observer) {
...
Comment 6 Edgar Mueller CLA 2012-05-02 06:05:35 EDT
Sorry, I don't get it yet.  If ProjectSpace implements LoginObserver and ProjectSpaceImpl extends ProjectSpaceBase then in my understanding a call to getObserverBus().unregister(this) in ProjectSpaceBase must remove the ProjectSpace instance from the ObserverBus.  This is also what the javadoc says you've pasted.  So why should there be a difference between unregister(this) and unregister(this, LoginObserver.class) regarding the unsubscription of the LoginObserver only.
Comment 7 Edgar Mueller CLA 2012-05-02 06:19:58 EDT
For refernce: Assuming that DImpl extends CImpl the following test would fail:

public void testSuperUnregister() {
	DImpl d = new DImpl();
	getObserverBus().register(d, C.class);
	assertEquals("42", getObserverBus().notify(C.class).fourtyTwo());
	getObserverBus().unregister(d);
	assertFalse("42".equals(getObserverBus().notify(C.class).fourtyTwo()));
}

I'll contact Otto, who wrote the ObserverBus whether this is intended behaviour.
Comment 8 Dmitry Litvinov CLA 2012-05-02 06:34:13 EDT
Yes, you are right, I didn't see that ProjectSpaceBase implements LoginObserver.
Comment 9 Dmitry Litvinov CLA 2012-05-02 07:01:24 EDT
Obviously, method ObserverBus#getClasses is wrong. You could use, for example ClassUtils#getAllInterfaces(Class cls) from org.apache.commons instead
Comment 10 Edgar Mueller CLA 2012-05-03 08:54:18 EDT
I've fixed the getClasses call by implementing our own getAllInterfaces method in ObserverBus directly.  I'd to close this ticket, since my proposed test works as we'd have expected.  But just to go sure, can you re-test, i.e. check whether the memory leak is gone now?