#15432: Use a callback with a weak reference to WeakValueDictionary
-------------------------------------+-------------------------------------
Reporter: nbruin | Owner:
Type: enhancement | Status: needs_review
Priority: major | Milestone: sage-6.0
Component: memleak | Resolution:
Keywords: | Merged in:
Authors: | Reviewers:
Report Upstream: N/A | Work issues:
Branch: | Commit:
u/nbruin/ticket/15432 | 9bb9241572468d4bc0563f06fe6fffcc8b12c345
Dependencies: | Stopgaps:
-------------------------------------+-------------------------------------
Comment (by nbruin):
Replying to [comment:3 SimonKing]:
> Just to make sure: Is there a dependency for this ticket? It seems that
we need #13394 (which is merged). But #15367 is orthogonal, isn't it?
The branch here descends directly from master, which recently had
5.13beta3 merged. Therefore, as posted, this ticket has no dependencies.
Since it only touches one file, that isn't even present in the branch for
#15367 (its branch split off before 5.13beta3 merger), I expect no merge
problems with that ticket.
I actually have a bit of trouble coming up with an example that shows a
difference in behaviour for !WeakValueDictionary (before this ticket it's
not weakly refererrable, making examples particularly tricky). With the
following code:
{{{
%cpaste
import gc
from sage.misc.weak_dict import WeakValueDictionary
from sage.structure.coerce_dict import MonoDict
def Nobj(t):
return len([1 for o in gc.get_objects() if isinstance(o,t)])
def TestTcollect(T,args=()):
N=Nobj(T)
print "Number of T-objects before we start:",N
L=[T(*args) for i in range(100)]
M=MonoDict(11)
for i in range(len(L)-1):
M[L[i]]=L[i+1]
Nnew=Nobj(T)
print "Number of T-objects after list construction:",Nnew
print "Throwing away references:"
del L
Nnew=Nobj(T)
if Nnew == N:
print "no GC required to get rid of objects";
j=0
while Nnew>N:
j+=1
_=gc.collect()
Ntemp=Nobj(T)
if Ntemp >= Nnew:
raise RuntimeError("we're not collecting at all!")
Nnew=Ntemp
print "number of collects required:",j
class dd(dict):
"a weakly reffable and easily recognized dict class"
pass
class selfref(object):
def __init__(self):
self.D=self
--
}}}
I'm getting with a self-referencing class:
{{{
sage: TestTcollect(selfref)
Number of T-objects before we start: 0
Number of T-objects after list construction: 100
Throwing away references:
number of collects required: 100
}}}
The test doesn't work for dict itself (they have their own freelist etc.
so
the object count you get back can't be trusted), but we can do it on a
subclass:
{{{
sage: TestTcollect(dd)
Number of T-objects before we start: 0
Number of T-objects after list construction: 100
Throwing away references:
no GC required to get rid of objects
number of collects required: 0
}}}
For this patched `WeakValueDictionary` we're still getting problematic
behaviour:
{{{
sage: TestTcollect(sage.misc.weak_dict.WeakValueDictionary)
Number of T-objects before we start: 29
Number of T-objects after list construction: 129
Throwing away references:
number of collects required: 100
}}}
Whereas python's own is clean:
{{{
sage: TestTcollect(weakref.WeakValueDictionary)
Number of T-objects before we start: 3
Number of T-objects after list construction: 103
Throwing away references:
no GC required to get rid of objects
number of collects required: 0
}}}
As is (at least our old) `TripleDict`:
{{{
sage: TestTcollect(sage.structure.coerce_dict.TripleDict,(11,))
Number of T-objects before we start: 180
Number of T-objects after list construction: 280
Throwing away references:
no GC required to get rid of objects
number of collects required: 0
}}}
So my guess is that we've overlooked another self reference in
!WeakValueDictionary.
Note that our previous `sage.misc.weak_dict.WeakValueDictionary` wasn't
weakly
referrable so this test doesn't apply in that case.
--
Ticket URL: <http://trac.sagemath.org/ticket/15432#comment:4>
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 unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.