Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 492156

Summary: Memory leak on open/close Session
Product: [Modeling] Sirius Reporter: Laurent Redor <laurent.redor>
Component: CoreAssignee: Laurent Redor <laurent.redor>
Status: CLOSED FIXED QA Contact: Florian Barbin <florian.barbin>
Severity: minor    
Priority: P3 CC: florian.barbin, julien.dupont
Version: unspecifiedKeywords: triaged
Target Milestone: 4.0.0M7   
Hardware: PC   
OS: Windows 10   
See Also: https://git.eclipse.org/r/71205
https://git.eclipse.org/c/sirius/org.eclipse.sirius.git/commit/?id=05d393f16858b6da2ff9e668bc7d087812ec262d
Whiteboard:
Attachments:
Description Flags
ModelingProjectWithMediumAirdFile.zip none

Description Laurent Redor CLA 2016-04-21 05:08:53 EDT
Created attachment 261143 [details]
ModelingProjectWithMediumAirdFile.zip

It's seems we have a memory leak on Sirius master.

Steps to reproduce:
* Display the heap status (Menu Window/Preferences/General/Show heap status)
* Launch the garbage collector (with the garbage next the heap status)
* Note the heap size
* Import and open the project "ModelingProjectWithMediumAirdFile" from ModelingProjectWithMediumAirdFile.zip
* Close the project
* Launch the garbage collector and note the heap size
* Open the project
* Close the project
* Launch the garbage collector and note the heap size
* Open the project
* Close the project
* Launch the garbage collector and note the heap size
* The heap size increases around 60Mo at each open/close --> KO
Comment 1 Laurent Redor CLA 2016-04-21 06:14:17 EDT
For information, before commit "[442133] Delegate and optimize resource unload when resource is removed", that is a potential culprit, the leak is already here (even if the retained objects are not the same : AirdResourceImpl are no longer retained before this commit but we have always SessionLazyCrossReferencer retained).
Comment 2 Julien Dupont CLA 2016-04-21 06:27:53 EDT
I could not reproduce problem.
I tested with 2 different environment:
First environment, a bundle Obeo Designer 8.1.2
Second environment an eclipse 4.5.2 (Mars.2) with Sirius from master.

In all case there are no memory leak with example joins during the reproction of scenario
Comment 3 Julien Dupont CLA 2016-04-21 09:52:39 EDT
I reproduced problem now.
The problem is reproducible with the 2 environments (bundle Obeo Designer 8.1.2
and an eclipse 4.5.2 (Mars.2) with Sirius from master)
I could not reproduce because no viewpoints were selected. 
If I selected viewpoint "Design" I reproduced problem with the eap size increased around 60Mo at each open/close.
Comment 4 Laurent Redor CLA 2016-04-21 11:34:44 EDT
After analysis, the problem can be considered as minor. Indeed, the problem occurs only if one of the semantic models of the session is referenced through its URI "http://www.eclipse.org/emf/2002/Ecore". It is the case of the joined project.
This project comes from an old issue and we don't know how to have a such reference. Indeed, if you open an ecore file (of a session) with the editor Sample Ecore Model Editor to reference a MM (through "Load Resource..."), the URI finally stored in aird is "platform:/plugin/org.eclipse.emf.ecore/model/Ecore.ecore". And there is no problem with this kind of URI.

Analysis of the current leak with the joined project:
The representations file contains a reference to the Ecore MM resource, through URI "http://www.eclipse.org/emf/2002/Ecore".

During the loading of the session, this resource is not added to the resource set of the Session (it has no ResourceSet).
Corresponding Stack:
	ModelUtils.getResource(ResourceSet, URI) line: 322	
	SemanticResourceGetter.collectTopLevelSemanticResources(DAnalysisSessionImpl) line: 50	
	SessionResourcesTracker$1.run() line: 145	
	TransactionalEditingDomainImpl.runExclusive(Runnable) line: 328	
	TransactionUtil.runExclusive(TransactionalEditingDomain, RunnableWithResult<? extends T>) line: 328	
	SessionResourcesTracker.getSemanticResources() line: 149	
	DAnalysisSessionImpl.getSemanticResources() line: 642	
	SessionLazyCrossReferencer.initialize() line: 49	
	SessionLazyCrossReferencer(LazyCrossReferencer).setTarget(Notifier) line: 125	
	BasicNotifierImpl$EAdapterList<E>.didAdd(int, E) line: 121	
	BasicNotifierImpl$EAdapterList<E>(BasicEList<E>).addUnique(E) line: 419	
	BasicNotifierImpl$EAdapterList<E>(AbstractEList<E>).add(E) line: 303	
	BasicNotifierImpl$EAdapterList<E>.add(E) line: 193	
	DAnalysisSessionImpl.registerResourceInCrossReferencer(Resource) line: 259	
	DViewOperations.updateSelectedViewpointsData(IProgressMonitor) line: 204	
	DAnalysisSessionImpl.open(IProgressMonitor) line: 1162	
	OpenRepresentationsFileJob.performOpenSession(IProgressMonitor) line: 149	
	OpenRepresentationsFileJob.runInWorkspace(IProgressMonitor) line: 113	
	OpenRepresentationsFileJob(InternalWorkspaceJob).run(IProgressMonitor) line: 39	
	Worker.run() line: 55	

But the SessionLazyCrossReferencer is added to this resource.

During the closing of the Session, the SessionLazyCrossReferencer is removed from all the resources of the resourceSet (but not from all semantic resources). So references to the SessionLazyCrossReferencer are kept from the Ecore MM (and so indirectly to all EObject of the closed Session).

To summarize at opening, the SessionLazyCrossReferencer is added to all semantic, controlled and "all sesssion" resources:
    org.eclipse.sirius.business.internal.session.danalysis.SessionLazyCrossReferencer.initialize():
        Collection<Resource> semanticResources = session.getSemanticResources();
        EList<Resource> controlledResources = session.getControlledResources();
        Set<Resource> allSessionResources = session.getAllSessionResources();
		
And at closing it is removed only from resources of the session ResourceSet:
    org.eclipse.sirius.business.internal.session.danalysis.DAnalysisSessionImpl.disableAndRemoveECrossReferenceAdapters():
        resourceSet.getResources()
Comment 5 Laurent Redor CLA 2016-04-21 11:59:18 EDT
Steps to reproduce to have a similar modeling project as the joined project (with the memory leak problem):
* Example using Ecore Tools modeler (but can be made by using another modeler)
* Create a Modeling Project
* Create an Ecore Model in this Modeling Project
* Add a new Class C1 in the root package
* Click on the "Add Model" contextual menu on "Project Dependencies"
* In the text field of the popup, write "http://www.eclipse.org/emf/2002/Ecore" (without double quote)
* Select the viewpoint Design of Ecore Tools
* Select the Class C1 in the Model Explorer
* In the Properties view, choose "EClass" as ESuper Type for C1

The representations file has now a reference to "http://www.eclipse.org/emf/2002/Ecore" for one of their semantic resources.
With Yourkit, you can see that at each opening/closing of this project, there is an additional instance of SessionLazyCrossReferencer.
Comment 6 Eclipse Genie CLA 2016-04-22 04:28:00 EDT
New Gerrit change created: https://git.eclipse.org/r/71205
Comment 8 Laurent Redor CLA 2016-04-25 08:21:51 EDT
Fixed with above commit
Comment 9 Florian Barbin CLA 2016-05-25 05:47:43 EDT
Verified on Sirius 4.0.0.RC1
Comment 10 Pierre-Charles David CLA 2016-06-24 08:01:49 EDT
Available in Sirius 4.0.0.