[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[m2m-atl-dev] ATL 3.0 architecture & ASMEMFModel Memory leak comes back to haunt?
|
Hello ATL devs,
In this mail, I'll try to re-describe how the EMF model memory leak
relates to the new ATL 3.0.0 architecture in CVS HEAD. Below, I'll
indicate how ATL HEAD differs from ATL 2.1:
Dennis Wagelaar schreef:
Hello devs,
Recently, the "extent.unload()" line was removed from ASMEMFModel's
dispose method. Calling "unload()" should indeed not be necessary, and
removing a Resource from its ResourceSet should suffice.
Some tests with running ATL via Ant on some UML2 models revealed that,
even though ATL's ResourceSet never grew larger, memory was leaking at
about 20MB per Ant run. I also found that a couple of models (profiles,
libraries) were not removed from the ResourceSet afterwards, because ATL
is not aware of them.
The problem in ATL is that we're constantly trying to clean up ATL's
static ResourceSet, while EMF happily auto-resolves and auto-loads
referenced models. I've committed a new branch to the ATL CVS
("ATL_Dynamic_ResourceSet") that uses dynamic ResourceSet instances,
which are coupled to ModelLoader instances. This required breaking the
existing API for loading/saving models. I've used that as an opportunity
to remove all unused and/or duplicated API for loading and saving.
In ATL HEAD, EMFModel no longer distinguishes between the main Resource
and referenced Resources. Instead, there is EMFModel.getResources().
There is still a static ResourceSet, which resides inside
EMFModelFactory (slightly overkill, as EMFModelFactory is in effect a
singleton).
ATL is currently trying to do its own garbage collection: when it's
cleanup time, EMFModel.dispose() removes all Resources from the static
ResourceSet. This ensures that even auto-loaded referenced models are
removed.
This approach is problematic, because:
======================================
- Only metamodels (EMFReferenceModels) have referenced resources in
addition to the main resource. Contrary the main resource, which is
*owned*, those referenced resources may be *shared*. Other metamodels
may reference the same shared resource(s). That means you cannot remove
them from the ResourceSet unless *all* metamodels using the same
ResourceSet are cleaned up.
- There is no way of knowing when *all* metamodels using the same
ResourceSet are cleaned up. The garbage collector can tell by checking
if there are any IModel and ResourceSet references left. As the
ResourceSet is static, the garbage collector cannot touch the Resources
inside it until the EMFModelFactory class is unloaded. That normally
happens when you shut down Eclipse.
The problem cannot be solved like this:
=======================================
- Making the ResourceSet in EMFModelFactory a dynamic field causes the
ResourceSet to be garbage collected as soon as the corresponding
EMFModelFactory is garbage collected. Currently, the EMFModelFactory is
a singleton, which resides in a static registry. EMFModelFactory is
garbage collected when Eclipse shuts down.
- Creating a separate ResourceSet for each EMFModel -- or a cluster of
EMFModels tied to one EMFReferenceModel -- will ensure that referenced
resources are *not shared*. This may cause severe aliasing problems,
however. In the case of cross-references between multiple loaded
(meta)models, the same Resource is loaded multiple times in multiple
ResourceSets. Multiple representations of the same model element lead to
all kinds of errors in ATL transformations, ranging from equality check
failures to implicit tracing resolve failures.
The problem was solved in the following way in ATL_Dynamic_ResourceSet:
=======================================================================
AtlModelHandlers no longer include model loading/saving methods.
Instead, they have a Factory Method for creating ModelLoaders. A
ModelLoader instance can be used for a single ATL run (or a chain of ATL
runs). Afterwards, the ModelLoader will be garbage collected, with
ResourceSet and all. Models no longer need to be explicitly disposed:
this functionality has been moved to the "finalize()" method of the
ModelLoader, which is automatically invoked by the garbage collector.
The code still uses "unload()", but at least it is only used in the
garbage collection thread and doesn't interfere with the main model
transformation algorithms.
Cheers,
The equivalent of a disposable ModelLoader is not available in the ATL
3.0.0 architecture. In addition, the ResourceSet is used in EMFInjector,
which does the bulk of the model loading now. IInjectors are singletons,
like ModelFactories.
Therefore, I'd like to see the return of ModelLoader (even if it gets a
different name), which is disposable and can be created by ModelFactory.
Any chance of seeing this happen? What are your opinions on this?
William: what do you think of an architecture change that involves
something like a ModelLoader?
Cheers,
Dennis