Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Releasing memory when closing a model
Releasing memory when closing a model [message #1753830] Fri, 10 February 2017 13:31 Go to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi,

I am working on an EMF-based application that has the ability to load and unload models without restarting the application.

When unloading a model, I try to clean up all contents of the resource set containing the model. My code looks something like this:

    // Remove all adapters (rs is an instance of ResourceSet)
    rs.eAdapters().clear();
    TreeIterator<Notifier> allContents = rs.getAllContents();
    while (allContents.hasNext()) {
      allContents.next().eAdapters().clear();
    }
   
    // Unload all resources
    for (Resource resource : rs.getResources()) {
      resource.unload();
    }

    // Remove all resources from resource set
    rs.getResources().clear();


However, the memory footprint of my application stays almost unchanged after running this code. This is problematic, since it leads to the heap quickly filling for very large models. The heap always grows when I load a model but never shrinks when I unload it.

I found some related information in this thread from 2009: https://www.eclipse.org/forums/index.php/t/136611/

According to that thread, there is not much I can do short of generating my code in a different way, since the EObject instances in memory are still reference each other and cannot be garbage collected. Is this true, and is it still the case in 2016?

Another possibly related observation is that after unloading a model as described in the code snippet above, the heap contains a very large number (600,000 for a large model) of instances of org.eclipse.emf.common.utils.CommonUtil$StringPool$SelfCleaningStringPoolEntry that did not exist before. Why is this the case?

Thank you in advance!

Vlad
Re: Releasing memory when closing a model [message #1753832 is a reply to message #1753830] Fri, 10 February 2017 13:45 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 5834
Registered: July 2009
Senior Member
Hi

If the whole model is really unused, it can be released, but you have to break every last external reference. It is easy for some reference to persist perhaps a package or validation registry. You need to use a memory profiler such as VisualVM to help find where the external reference is then all the internal references garbage collect. NB remember that when debugging, your debugger's stack frame may have a reference, so as well as nulling working variables you may want to return a stack level before expecting things to really vanish.

Regards

Ed Willink
Re: Releasing memory when closing a model [message #1753838 is a reply to message #1753832] Fri, 10 February 2017 14:58 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 29311
Registered: July 2009
Senior Member
As Ed pointed out, you need to use a tool that lets you find the GC roots that are holding on to any object that you expect should be garbage collected. Note that unloading a resource will call org.eclipse.emf.ecore.resource.impl.ResourceImpl.unloaded(InternalEObject) for each object, and that will already clear the adapters, so you don't need to do that explicitly. Note that this method also turns the object into a proxy, i.e., sets the eProxyURI. This takes space, so unloading a resource will take more space that before you unloaded it, and if any object is still referenced anywhere else in your application it's generally the case that no object in the tree that was contained by the unloaded resource can be garbage collected. So you need to figure out where in your application you still have references to the unloaded objects... E.g., the command stack, if you don't flush it, will still contain references...
Re: Releasing memory when closing a model [message #1753844 is a reply to message #1753838] Fri, 10 February 2017 16:08 Go to previous messageGo to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi again,

Thank you both for the clarifications. I will remove the explicit code for clearing the adapters and look into heap dump to see if I can find remaining references to my model.

Cheers,
Vlad
Re: Releasing memory when closing a model [message #1754115 is a reply to message #1753844] Tue, 14 February 2017 15:17 Go to previous messageGo to next message
Vlad Acretoaie is currently offline Vlad AcretoaieFriend
Messages: 93
Registered: April 2014
Member
Hi again,

I made significant progress towards completely removing any references to the unloaded model using VisualVM.

A group of references that I am not sure need to be removed are the ones between the global package registry and my packages. Namely, should my code for unloading a model include something like the snippet below?

EPackage.Registry.INSTANCE.remove(IMyCustomPackage.eNS_URI);


Executing this code implies that the package must be registered again before a new model can be loaded.

Cheers,
Vlad
Re: Releasing memory when closing a model [message #1754137 is a reply to message #1754115] Tue, 14 February 2017 16:46 Go to previous messageGo to next message
Ed Willink is currently offline Ed WillinkFriend
Messages: 5834
Registered: July 2009
Senior Member
Hi

It depends how much memory you want to free up.

If you want to lose your metamodel, then you need to remove it from the package registry, and install it again, if you want it again.

If you only want to lose your models, then you should be able to leave the metamodel be. You 'just' need to eliminate the references that are locking your model in memory.

Regards

Ed Willink
Re: Releasing memory when closing a model [message #1754140 is a reply to message #1754137] Tue, 14 February 2017 17:13 Go to previous message
Ed Merks is currently offline Ed MerksFriend
Messages: 29311
Registered: July 2009
Senior Member
No, you should typically not be messing with the global package registry programmatically. A generated package is registered automatically during class loading and best you not undo that. You should only be concerned about freeing up your instances...
Previous Topic:Error in package registration while loading state machine from .uml
Next Topic:Problem with loading model in Sample Reflective Editor
Goto Forum:
  


Current Time: Fri Apr 20 01:25:44 GMT 2018

Powered by FUDForum. Page generated in 0.02417 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software