Issue494514
Created on 2001-12-18.08:58:51 by anonymous, last changed 2001-12-18.12:52:53 by bckfnn.
Messages | |||
---|---|---|---|
msg529 (view) | Author: Nobody/Anonymous (nobody) | Date: 2001-12-18.08:58:51 | |
Samuele, Thanks for the workaround. As this seems to confirm the bug on another platform, here is the bug report. FROM: Samuele Pedroni DATE: 12/17/2001 12:34:08 SUBJECT: RE: [Jython-dev] Python object not gc()'d, 21b1 Hi, use print 'Goodbye2 ' + repr(self) instead of println('Goodbye2 ' + repr(self)) and retry <wink>. PS: the explanation is left as an exercise to the reader :) I did the exercise. It was good fun, butI failed :( . I concluded there is some interaction between compiled code and the jython runtime that I do not know enough about. I stopped at Py.getFrame() and the asymmetry between PyFrame.f_globals and PyFrame.getf_locals(). I hope I was correct to conclude that this is a dead alley in this case. However since you call this an exercise, I am sure you can explain what is going on here :) Thanks for trying to confirm the strange behaviour, and thanks in advance for your explanation. Have fun, Ype (a teacher in a previous life) ----- Original Message ----- From: Ype Kingma <<EMAIL: PROTECTED>> To: <<EMAIL: PROTECTED>> Sent: Monday, December 17, 2001 8:45 PM Subject: [Jython-dev] Python object not gc()'d, 21b1 > Dear jythoneers, > > This is a rather involved bug, so I hope it is JVM dependent. > It shows up in rather unusual circumstances. > > Showing the bug involves running the tstdel.py file > from the command line. This program execfile()'s > the modules tstdel1.py and tstdel2.py > which differ only slightly. > All three program files are included in this post, see below. > > The tstdel.py program gives the output shown below. > Each output line mentioning an object is printed > from a constructor ('Hello' and 'Hello2') or > from a __del__(self) method ('Goodbye' and Goodbye2') > in the execfile()'d programs. > > The output indicates that when using an object of > class executor the deltest2 object is correctly gc()'d. > However when an object of class clearingExecutor is > used the deltest2 object is not gc()'d, even after > the clearingExecutor is del'ed: > (jython 21b1, java 1.1.8, OS2) > > <output from tstdel.py> > > __main__.executor > Hello <unknown>.deltest1 instance at 390229> > Hello2 <unknown>.deltest2 instance at 296443> > after del __main__.executor > Goodbye <unknown>.deltest1 instance at 390229> > Goodbye2 <unknown>.deltest2 instance at 296443> > > __main__.clearingExecutor > Hello <unknown>.deltest1 instance at 298665> > Goodbye <unknown>.deltest1 instance at 298665> > Hello2 <unknown>.deltest2 instance at 293293> > after del __main__.clearingExecutor > > <end of output from tstdel.py> > > Before the executor object is del'ed it references > a deltest1 and a deltest2 object, and after the executor object > is del'ed both the deltest1 object and the deltest2 object > are __del__()'d. This is expected, and it might exclude the > possibility of dangling references from java classes created > to perform execfile(). > > The clearingExecutor correctly clears the deltest1 instance > from its self.glb, as is seen in the Goodbye from the deltest1 > instance at 298665, which is output before the next Hello2. > > The bug: > Even before deleting the clearningExecutor > I would expect a Goodbye2 from the > deltest2 instance at 293293. > But this deltest2 instance is not __del__()'ed, > not even after del'ing the clearingExecutor object. > There seems to be a dangling reference > to the deltest2 object at 293293. > > > <The main program tstdel.py:> > > from java.lang.System import gc, runFinalization > from time import sleep > > class executor: > def __init__(self): > self.glb = {} > > def exf(self, fnam): > execfile(fnam, self.glb, self.glb) > > > class clearingExecutor: > def __init__(self): > self.glb = {} > > def exf(self, fnam): > execfile(fnam, self.glb, self.glb) > self.glb.clear() > > > def cleanUp(): > gc() > runFinalization() > sleep(2) > > > x = executor() > y = clearingExecutor() > > print x.__class__ > > x.exf('tstdel1.py') > cleanUp() > > x.exf('tstdel2.py') > cleanUp() > > print 'after del', x.__class__ > del x > > cleanUp() > > print ' > print y.__class__ > > y.exf('tstdel1.py') > cleanUp() > > y.exf('tstdel2.py') > cleanUp() > > print 'after del', y.__class__ > del y > > cleanUp() > > cleanUp() > > > <end of tstdel.py> > > <The tstdel1.py program:> > > import java > println = java.lang.System.out.println > > class deltest1: > def __init__(self): > self.println = java.lang.System.out.println > self.println('Hello ' + repr(self)) > > def __del__(self): > self.println('Goodbye ' + repr(self)) > > td1 = deltest1() > > <end of tstdel1.py> > > The tstdel2.py program: > > import java > println = java.lang.System.out.println > > class deltest2: > def __init__(self): > self.println = java.lang.System.out.println > self.println('Hello2 ' + repr(self)) > > def __del__(self): > println('Goodbye2 ' + repr(self)) > > td2 = deltest2() > > <end of tstdel2.py program> > > The only difference (apart from names) between tstdel1.py and tstdel2.py > is in the __del__() method. Class deltest2 references a > function in module scope to provide its output, class deltest1 > uses the same function but as one of its attributes. > > This difference seems to cause a deltest2 object to never become > garbage when the dictionary against which tstdel2.py is executed > is clear()'d. > > It is possible that this bug is related to the 'NameError: tracer' > I posted earlier (I gave up to isolate this possible bug). > If/when these two are related a possible explanation would be > that in some execution frame there is a wrong reference to an > earlier frame. This could in this case form a dangling reference > and in the 'NameError: tracer' case cause a deletion from the > wrong namespace. > > Again, I do hope that this one is platform dependent. > If not, I'll gladly report a bug on sourceforge... > > Have fun, > Ype > > P.S. 21b1 is otherwise working very well for me. > |
|||
msg530 (view) | Author: Nobody/Anonymous (nobody) | Date: 2001-12-18.09:12:28 | |
Logged In: NO Sourceforge didn't allow me to login, and somehow all the indentation got lost, leaving Samuel's message and my answer not distinguished by layout. This also made a mess of the python code. See jython-dev for the originals. You can reach me on jython-dev or via ype@users.sourceforge.net. |
|||
msg531 (view) | Author: Finn Bock (bckfnn) | Date: 2001-12-18.11:48:35 | |
Logged In: YES user_id=4201 It isn't really a mystery and exactly the same thing happens in CPython. When the __del__() is executed, the globals no longer have a reference to the module level println function. The result is a common NameError exception. Unfortunately Jython 2.1b1 doesn't inform you of the xception in the way it should. |
|||
msg532 (view) | Author: Finn Bock (bckfnn) | Date: 2001-12-18.12:45:13 | |
Logged In: YES user_id=4201 Added as test349.py. |
|||
msg533 (view) | Author: Finn Bock (bckfnn) | Date: 2001-12-18.12:52:53 | |
Logged In: YES user_id=4201 Fixed in PyFinalizableInstance.java: 2.5; |
History | |||
---|---|---|---|
Date | User | Action | Args |
2001-12-18 08:58:51 | anonymous | create |
Supported by Python Software Foundation,
Powered by Roundup