python - Hidden references to function arguments causing big memory usage? -


edit: never mind, being stupid.

i came across code recursion on smaller , smaller substrings, here's essence plus testing stuff:

def f(s):     if len(s) == 2**20:         input('check memory usage again')     else:         f(s[1:]) input('check memory usage, press enter') f('a' * (2**20 + 500)) 

before call, python process takes 9 mb (as checked windows task manager). after 500 levels ~1mb strings, it's @ 513 mb. no surprise, each call level still holding on string in s variable.

but tried fix replacing reference string reference new string , still goes 513 mb:

def f(s):     if len(s) == 2**20:         input('check memory usage again')     else:         s = s[1:]         f(s) input('check memory usage, press enter') f('a' * (2**20 + 500)) 

why doesn't let go off memory? strings smaller, later strings fit space of earlier strings. there hidden additional references strings somewhere or going on?

i had expected behave this, goes 10 mb (a change of 1 mb, expected because new string built while old string still exists):

input('check memory usage, press enter') s = 'a' * (2**20 + 500) while len(s) != 2**20:     s = s[1:] input('check memory usage again') 

(never mind poor time complexity, btw, know that, don't bother.)

your function recursive, when call f(), current frame put onto stack, , new 1 created. each function call keeps reference new string creates pass down next call.

to illustrate stack

import traceback  def recursive(x):     if x:         recursive(x[1:])     else:         traceback.print_stack()  recursive('abc') 

gives

$ python tmp.py   file "tmp.py", line 10, in <module>     recursive('abc')   file "tmp.py", line 5, in recursive     recursive(x[1:])   file "tmp.py", line 5, in recursive     recursive(x[1:])   file "tmp.py", line 5, in recursive     recursive(x[1:])   file "tmp.py", line 7, in recursive     traceback.print_stack() 

when final call recursive() returns, returns next call above still has reference x.

but tried fix replacing reference string reference new string , still goes 513 mb

well did in current function being called, function called still has reference passed in. e.g.

def foo(x):     print "foo1", locals()     bar(x)     print "foo2", locals()  def bar(x):     print "bar1", locals()     x = "something else"     print "bar2", locals()  foo('original thing') 

when foo() called, passes string 'original thing' bar(). , though bar() gets rid of reference, current call above foo() still has reference

$ python tmp_x.py  foo1 {'x': 'original thing'} bar1 {'x': 'original thing'} bar2 {'x': 'something else'} foo2 {'x': 'original thing'} 

i hope illustrates it. have been little vague in first statement stack frames.


Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -