Actually this appears to be the correct behavior! There's another way to get
at the frame and that's via sys.exc_info(). This modified version, which runs
on both IronPython and CPython and prints the same thing, shows how you get
back to the list:
import sys
def f():
def coroutine():
just_numbers = range(1,1000000)
def inner_method():
return just_numbers
yield None
raise Exception("some exception") # comment out this line to make
the test not work
crt = coroutine()
try:
crt.next()
crt.next()
except:
pass
crt = None
print len(sys.exc_info()[2].tb_next.tb_frame.f_locals['just_numbers'])
f()
From: [email protected]
[mailto:[email protected]] On Behalf Of Dino Viehland
Sent: Thursday, February 18, 2010 8:16 AM
To: Discussion of IronPython
Cc: Ronnie Maor; Avner Rosenan
Subject: Re: [IronPython] Bug fixes in Ipy 2.6.1
This is interesting - there's a .NET exception object which is keeping a
traceback frame alive which is keeping the just_numbers list alive. We should
clear out the local .NET exception and the memory will then be eligible for
collection. The good news is that as soon as this method is no longer on the
stack the memory is reclaimable (so it's really just that we're not collecting
soon enough - not that we're actually leaking the memory) but we should fix it
anyway.
I've opened this bug:
http://ironpython.codeplex.com/WorkItem/View.aspx?WorkItemId=26244
From: [email protected]
[mailto:[email protected]] On Behalf Of Idan Zaltzberg
Sent: Thursday, February 18, 2010 2:58 AM
To: [email protected]
Cc: Ronnie Maor; Avner Rosenan
Subject: [IronPython] Bug fixes in Ipy 2.6.1
Hi,
In Ipy 2.6 there some issues of memory leak when using generator methods.
I downloaded Ipy 2.6.1 RC1 and indeed most of them were fixed.
Still, one issue still remains the same but I'm not entirely sure this is a
real bug:
The following code shows that in some cases, some memory is not released even
after GC, is that ok?
def coroutine():
just_numbers = range(1,1000000)
def inner_method():
return just_numbers
yield None
raise Exception("some exception") # comment out this line to make
the test not work
from System import GC
def get_memory():
for _ in xrange(4):
GC.Collect()
GC.WaitForPendingFinalizers()
return GC.GetTotalMemory(True)/1e6
before = get_memory()
crt = coroutine()
try:
crt.next()
crt.next()
except:
pass
crt = None
after = get_memory()
self.assert_(after-before > 10,'There should be a memory leak in this
case.before=%s after=%s' % (before,after))
_______________________________________________
Users mailing list
[email protected]
http://lists.ironpython.com/listinfo.cgi/users-ironpython.com