Destruction of Objects with Cyclic References: MATLAB automated procedure is much too slow, how to turn it off (and reimplement a solution fitted to my needs by writing proper destructor methods)?
7 views (last 30 days)
Show older comments
I need to construct a lot of instances of classes that are interconnected, where properties of the objects contain handles of other objects. When Matlab wants to delete these objects, it takes a huge amount of time (seems to be quadratic or even worse). It is due to the fact that the Handle Class Destructor in Matlab features a particular procedure for “Destruction of Objects with Cyclic References”:
From "Handle Class Destructor" documentation: Consider a set of objects that reference other objects of the set such that the references form a cyclic graph. In this case, MATLAB:
- destroys the objects if they are referenced only within the cycle
- does not destroy the objects as long as there is an external reference to any of the objects from a MATLAB variable outside the cycle
The problem is that this method causes these terribly slow performances: For each object, the procedure has to find those cyclic dependencies, which takes a lot of time.
I found a first solution to the problem: I just tell Matlab that when one of these objects has to be deleted, we can be sure that we can delete all the referenced objects as well. No need to check for cycle. For that, in the destructor of a given class, I call the destructor of all the referenced objects. This works in simple cases with not many objects, the garbage collection is much faster. But there is a hiccup: all these recursive calls to “delete” leads to stack overflow when the number of objects is larger.
So the optimal solution, in my sense, would be to toggle off the automated deletion of objects with cyclic references and to perform all the deletion manually (by writing the destructor of each class appropriately). But how to toggle off the automated deletion of objects with cyclic references? That is the question...
Any thought?
7 Comments
David Foti
on 23 Feb 2017
I know it has been a while and my apologies for the long time since this question was posted, but I believe that R2016b MATLAB contains a fix for the slow destruction with this newer version. I now see the clear taking about 2 seconds vs. hundreds before.
The issue was in bookkeeping during destruction of a graph when all nodes are dead (when the last variable is to the root node is cleared). When MATLAB is unable to find a parent graph node that is still reachable by a MATLAB variable, it remembers that all nodes along all paths searched from the starting node are also unreachable so it should not try to traverse those same paths again. However, an interaction with MATLAB's shared data mechanism meant that this cache was getting cleared when one of the nodes was an array that was referenced from two different places (MATLAB makes actual copies of arrays only when the array is changed and otherwise shares the data). In R2016b, the condition that causes the cached information to be invalidated was tightened.
Answers (2)
Philip Borghesani
on 6 May 2016
There is no way to toggle off the detection algorithms, doing so would cause enough objects to leak that MATLAB would probably become unusable in a short time.
1 Comment
David Foti
on 9 May 2016
Hi Olivier,
Thank you for providing instructions to see the issue. Based on the way the seq.Sequence is being used, I wonder if you intended it to be a handle class? It appears that every event has a sequence stored in a property. This sequence will be a copy of the object passed to the event constructor with however many events have been added to its contents at the time the event is created. In your example, this leads to a huge number of copies of objects that each reference a potentially huge number of events. I can't find usage in the class files that indicates a need for each event to have its own copy of the sequence contents and the call to the integrate method on line 42 of seq.event doesn't capture the updated sequence object which suggests to me a possible expectation that sequence behaves like a handle and is modified by the integrate method.
If I change seq.Sequence to subclass handle, clearing the workspace takes about 6 seconds for me. Does it make sense for seq.Sequence to be a handle? If not, is there a way for events to avoid needing a copy of the sequence? Could they instead store only the information they need?
2 Comments
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!