#11521: Memleak when resolving the action of Integers on an Elliptic Curve
------------------------+---------------------------------------------------
   Reporter:  jpflori   |          Owner:  robertwb    
       Type:  defect    |         Status:  needs_review
   Priority:  major     |      Milestone:  sage-4.7.2  
  Component:  coercion  |       Keywords:              
Work_issues:            |       Upstream:  N/A         
   Reviewer:            |         Author:              
     Merged:            |   Dependencies:              
------------------------+---------------------------------------------------

Comment(by jpflori):

 I'm having a look at your problem right now. Here are some hints to study
 the problem, mostly stolen from
 [http://trac.sagemath.org/sage_trac/search/opensearch?q=ticket%3A10548
 #10548].

 I put it here for the record, and so that i can go faster next time.

 First, if I only create the finite fields and do nothing with them, I do
 not seem to get a memleak. Some fields are not garbage collected
 immediately, but calling gc.collect() does the trick.

 {{{
 sage: import gc
 sage: for p in prime_range(10**5):
 ....:    k = GF(p)
 ....:
 sage: del p, k
 sage: gc.collect()
 1265
 sage: from sage.rings.finite_rings.finite_field_prime_modn import
 FiniteField_prime_modn as FF
 sage: L = [x for x in gc.get_objects() if isinstance(x, FF)]
 sage: len(L)
 1
 sage: L
 [Finite Field of size 2]

 }}}
 Of course I guess you actually do something with your finite fields.

 So here is a small example causing the fields to stay cached.

 {{{
 sage: import gc
 sage: for p in prime_range(10**5):
 ....:    k = GF(p)
 ....:
 sage: del p, k
 sage: gc.collect()
 0

 }}}
 The zero here is bad and indeed

 {{{
 sage: from sage.rings.finite_rings.finite_field_prime_modn import
 FiniteField_prime_modn as FF
 sage: L = [x for x in gc.get_objects() if isinstance(x, FF)]
 sage: len(L)
 9592

 }}}
 If you want to know where it comes from you can use the objgraph python
 module (on my debian I just installed the python-objgraph package, updated
 sys.path in Sage to include '/usr/lib/python2.6/dist-packages')

 {{{
 sage: sys.path.append('/usr/lib/python2.6/dist-packages')
 sage: import inspect, objgraph
 sage:
 objgraph.show_backrefs(L[-1],filename='/home/jp/br.png',extra_ignore=[id(L)])

 }}}
 And look at the png or use

 {{{
 sage: brc =
 
objgraph.find_backref_chain(L[-1],inspect.ismodule,max_depth=15,extra_ignore=[id(L)])
 sage: map(type,brc)
 [<type 'module'>, <type 'dict'>, <type 'dict'>,...
 sage: brc[0]
 <module 'sage.categories.homset'...

 }}}
 So the culprit is "_cache" in sage.categories.homset which has a direct
 reference to the finite fields in its keys.

 The clean solution woul be to used weakref in the keys (let's say
 something as WeakKeyDirectory in python).

 However, resetting cache should be a (potentially partial) workaround (and
 could kill your Sage?).

 {{{
 sage: sage.categories.homset.cache = {}
 sage: gc.collect()
 376595

 }}}
 It also seems to be enough if I do "a = k.random_element(); a = a+a" in
 the for loop, but not if I add "a = 47*a+3".

 I'm currently investigating that last case.

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/11521#comment:8>
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.

Reply via email to