#12616: The LP are not deallocated because of cyclic references !
----------------------------------+-----------------------------------------
Reporter: ncohen | Owner: ncohen
Type: defect | Status: needs_review
Priority: major | Milestone: sage-5.0
Component: linear programming | Keywords:
Work_issues: | Upstream: N/A
Reviewer: | Author: Nathann Cohen
Merged: | Dependencies:
----------------------------------+-----------------------------------------
Comment(by SimonKing):
Hi Nathann,
Replying to [comment:12 ncohen]:
> > In the ticket description, you mention a few reports on memory leaks.
Is the objective of this ticket to fix all of them?
I think I stand corrected in what I said about Python's garbage collector.
If I am not mistaken, the garbage collector is involved ''only'' if there
are reference cycles. Hence, if an object deleted and is not contained in
a reference cycle, it will be immediately removed, even if garbage
collection is switched off:
{{{
sage: class C:
....: def __del__(self):
....: print "deleting the object"
....:
sage: class D:
....: pass
....:
sage: c = C()
sage: import gc
sage: gc.disable()
sage: del c
deleting the object
}}}
Hence, since your patch destroys one reference cycle, it makes sure that a
deleted mixed integer linear program will be immediately removed.
Here is an example in which garbage collection comes in. The slight
problem is that if one has a `__del__` method in the cycle, then the
garbage collector does not know what to do. Hence, in my example, I am
creating a cycle of instances of D, with a pointer to an instance of C,
such that one sees when things are deleted:
{{{
sage: d1 = D()
sage: d2 = D()
sage: d1.d = d2
sage: d2.d = d1
sage: c = C()
sage: d1.c = c
sage: del d1
sage: del c
sage: del d2
}}}
Nothing happens! The `__del__` method of c is not called!! Hence, with
garbage collection disabled, the reference cycle `d1 <--> d2` can not be
removed.
Let's do the collection manually:
{{{
sage: gc.collect()
deleting the object
681
}}}
Aha! The reference cycle, and thus the last reference to c, has gone.
The last example shows that we must not have `__del__` in the reference
cycle:
{{{
sage: d = D()
sage: c = C()
sage: d.c = c
sage: c.d = d
sage: del c
sage: del d
sage: gc.collect()
4
sage: len([x for x in gc.get_objects() if isinstance(x,C)])
1
}}}
So, c is not deleted and will not be deleted! That would be a memory leak.
What does that mean for your patch?
- I still believe it is a good idea to avoid reference cycles, when
possible. However, I don't think that your patch fixes an actual leak.
- By now, I think that your example ''does'' demonstrate the fix, and
that it works stably.
So, let me run doctests, and if they pass, I give it a positive review.
--
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/12616#comment:13>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica,
and MATLAB
--
You received this message because you are subscribed to the Google Groups
"sage-trac" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sage-trac?hl=en.