Releasing memory when closing a model [message #1753830] |
Fri, 10 February 2017 13:31 |
Vlad Acretoaie Messages: 95 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 #1753838 is a reply to message #1753832] |
Fri, 10 February 2017 14:58 |
Ed Merks Messages: 33217 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...
Ed Merks
Professional Support: https://www.macromodeling.com/
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03741 seconds