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
Post a Comment