Issue494514

classification
Title: Python object not gc()'d
Type: Severity: normal
Components: Core Versions:
Milestone:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: bckfnn Nosy List: bckfnn, nobody
Priority: normal Keywords:

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:51anonymouscreate