On 21 Jan 2005 11:13:20 -0800, "Johnny Lin" <[EMAIL PROTECTED]> wrote:
>thanks everyone for the replies! > >John Hunter, yep, this is Johnny Lin in geosci :). > >re using return: the problem i have is somewhere in my code there's a >memory leak. i realize return is supposed to unbind all the local >variables, but since the memory leak is happening despite return, i >thought it might help me track down the leak if i unbound everything >explicitly that i had defined in local scope before i returned. or if >anyone has recomm. on plugging leaks, would be thankful for any >pointers there too. It helps to clue people into what your real goal is ;-) (Your initial post said nothing about memory leaks). Step 1: How do you know you have a memory leak? Python retains some memory in internal free pools rather than returning it to the OS, so you might not have a memory leak at all, in the true sense. If you are having a real memory leak, look first at any C extensions you've written yourself, then at other's alpha/beta stuff you may be using. Core CPython is probably the last place to look ;-) If you are creating reference loops, I think some may be uncollectable. I'm not sure how you are detecting "memory leaks," but whatever the method, if you can write a test harness that will create a zillion of each suspect thing and delete them in turn, and print out your detection data -- even if you have to run separate processes to do it, that might narrow down your search. E.g., if you write a little test.py that takes a command line argument to choose which object to create zillions of, and print out leak evidence, then you could run that systematically via popen etc. Or just run test.py by hand if you don't have that many suspects (hopefully the case ;-) > >my understanding about locals() from the nutshell book was that i >should treat that dictionary as read-only. is it safe to use it to >delete entries? Well, it's not read-only, but it doesn't write through to the actual locals. Think of it as a temp dict object with copies of the local name:value bindings, but changing anything in it only changes the temp dict object in the usual way. UIAM ;-) (OTOH, deletions of actual local bindings do seem to propagate back into a previously bound value of locals on exit, and a new call to locals() seems to return the same identical object as before, so I'm not sure I believe the <type 'dict'>, unless it has a special slot and it is automatically updated at exit. But a local bare name assignment or deletion doesn't immediately propagate. But it does on exit. So the <type 'dict'> returned by locals() has a special relationship to the function it reflects, if it is otherwise a normal dict: >>> def foo(x): ... d = locals() ... print '1:',id(d), type(d), d ... del x ... print '2:',id(d), type(d), d ... del d['x'] ... print '3:',id(d), type(d), d ... y = 123 ... print '4:',id(d), type(d), d ... d['z'] = 'zee' ... print '5:',id(d), type(d), d ... return d, locals() ... >>> dret, endinglocals = foo('arg passed to foo') 1: 49234780 <type 'dict'> {'x': 'arg passed to foo'} 2: 49234780 <type 'dict'> {'x': 'arg passed to foo'} 3: 49234780 <type 'dict'> {} 4: 49234780 <type 'dict'> {} 5: 49234780 <type 'dict'> {'z': 'zee'} >>> dret {'y': 123, 'z': 'zee', 'd': {...}} >>> endinglocals {'y': 123, 'z': 'zee', 'd': {...}} >>> dret is endinglocals True >>> dret['d'] is dret True (the {...} is an indication of the recursive reference) Note that at 2: the del x was not reflected, nor did the y = 123 show at 4: But the d['z'] showed up immediately, as you might expect ... but d['z'] also in that last returned locals(), which you might not expect, since there was no assignment to bare z. But they are apparently the same dict object, so you would expect it. So maybe there is some kind of finalization at exit like closure building. Anyway, d = dict(locals()) would probably behave differently, but I'm going to leave to someone else ;-) Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list