|
From: Ype K. <yk...@xs...> - 2001-12-17 19:36:16
|
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.
|