Message58218
Finally I found a potential problem with the garbage collector in a
specific case:
- Some object C participates in a reference cycle, and contains a
reference to another object X.
- X.__del__ 'resurrect' the object, by saving its 'self' somewhere else.
- X contains a reference to Y, which has a __del__ method.
When collecting all this, gc.garbage == [Y] !
This is not true garbage: if you clean gc.garbage, then the next
gc.collect() clears everything.
Now, try to follow my explanation (if I correctly understand the gc
internals):
- When the cycle is garbage collected, X and Y are detected as
'unreachable with finalizers', and put in a specific 'finalizers' list.
- the cycle is broken, C is deallocated.
- This correctly triggers X.__del__. X is removed from the 'finalizers'
list.
- when X is resurrected, it comes back to the normal gc tracking list.
- At the end, 'finalizers' contains 3 objects: X.__dict__, Y and Y.__dict__.
- Y is then considered as garbage.
I join a script which reproduces the behaviour. Note that 2.4 and 2.5
are affected too.
In py3k, the 'resurrect' seems to be caused by a (caught) exception in
TextIOWrapper.close(): the exception contains a reference to the frame,
which references the self variable. |
| File name |
Uploaded |
|
gc_bug.py
|
amaury.forgeotdarc,
2007-12-05.16:51:42
|
|
| Date |
User |
Action |
Args |
| 2007-12-05 16:51:43 | amaury.forgeotdarc | set | spambayes_score: 0.0121922 -> 0.012192151 recipients:
+ amaury.forgeotdarc, gvanrossum, christian.heimes |
| 2007-12-05 16:51:42 | amaury.forgeotdarc | set | spambayes_score: 0.0121922 -> 0.0121922 messageid: <[email protected]> |
| 2007-12-05 16:51:42 | amaury.forgeotdarc | link | issue1540 messages |
| 2007-12-05 16:51:42 | amaury.forgeotdarc | create | |
|