
[Originally posted to comp.lang.python with no response; asking here before filing a bug report] Is garbage collection supposed to run when Python exits? The following program does not print any output, unless I uncomment the gc.collect() (or add a for loop that forces GC after creating the cycle): import gc class A: pass class B: def __del__(self): print "Bye-bye!" a = A() b = A() a.b = b b.a = a a.x = B() del a del b #gc.collect() -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "I disrespectfully agree." --SJM

On Sun, Dec 29, 2002, Tim Peters wrote:
Thanks. I'll tell people to run gc.collect() at the end of their applications if they care. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "There are three kinds of lies: Lies, Damn Lies, and Statistics." --Disraeli

Aahz wrote:
The language reference manual doesn't promise that any garbage will be collected, ever. So, no, "supposed to" doesn't apply.
Thanks. I'll tell people to run gc.collect() at the end of their applications if they care.
Why? When application exits the OS would reclaim it's memory pages anyway. -- Bst rgrds, M.A.X.: Mechanical Artificial Xenomorph.

On Thu, Jan 02, 2003, Max Ischenko wrote:
Because garbage cycles can point at non-garbage; when the garbage is reclaimed, __del__() methods will run. You could argue that this is another reason against using __del__(), but since this is part of the way CPython works, I'm documenting it in my book. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "There are three kinds of lies: Lies, Damn Lies, and Statistics." --Disraeli

[Aahz]
Because garbage cycles can point at non-garbage; when the garbage is reclaimed, __del__() methods will run.
When cycles contain `__del__()', they are wholly added to gc.garbage if I understand the documentation correctly, and so, `__del__()' will not be run. -- François Pinard http://www.iro.umontreal.ca/~pinard

On Thursday 02 January 2003 03:47 pm, François Pinard wrote:
Yes, but that doesn't affect Aahz's argument -- consider, e.g.: class Nodel: pass class Hasdel: def __del__(self): print 'del(%s)'%self a, b, c = Nodel(), Nodel(), Nodel() a.x = b; b.x = c; c.x = a b.y = Hasdel() del a, b, c import gc # gc.collect() Here, the __del__ method is never run, but, if you uncomment the gc.collect call, then the __del__ method IS run -- just as Aahz said. Alex

[François Pinard]
When cycles contain `__del__()', they are wholly added to gc.garbage if I understand the documentation correctly, and so, `__del__()' will not be run.
True, but objects that are not *in* a cycle but that were kept alive because the cycle referenced them will have their __del__ methods run when the cycle is GC'ed. --Guido van Rossum (home page: http://www.python.org/~guido/)

Aahz wrote:
Documenting that you can call gc.collect() at the end is good; documenting that you should call it is not. I would expect that in many cases, it will be irrelevant whether __del__ is called at the end or not, as the system or the underlying libraries will reclaim whatever resources have been acquired. If you need to guarantee that __del__ is called at the end for all objects, you have probably much bigger problems in your application than that, and it is likely better to explicitly break any remaining cycles than to invoke gc.collect. Regards, Martin

On 02 January 2003, Aahz said:
As I recall (and this knowledge dates back to 1997 or so, so could well be obsolete), Perl does a full GC run at process exit time. In normal contexts this is irrelevant; I believe the justification was to clean up resources used by an embedded interpreter. Greg -- Greg Ward <gward@python.net> http://www.gerg.ca/

Embedded interpreters may do this, but the "main" interpreter may still not do this. The only time the "main" interpreter would benefit from this is if there are external resources that otherwise don't get cleaned up when the process exits (e.g. temp files). --Guido van Rossum (home page: http://www.python.org/~guido/)

[Greg Ward]
See http://tinyurl.com/41wy searching down for "Two-Phased Garbage Collection". Perl's mark-&-sweep phase runs when a thread terminates, which includes the main thread exiting, but isn't really aimed at that.

On Sun, Dec 29, 2002, Tim Peters wrote:
Thanks. I'll tell people to run gc.collect() at the end of their applications if they care. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "There are three kinds of lies: Lies, Damn Lies, and Statistics." --Disraeli

Aahz wrote:
The language reference manual doesn't promise that any garbage will be collected, ever. So, no, "supposed to" doesn't apply.
Thanks. I'll tell people to run gc.collect() at the end of their applications if they care.
Why? When application exits the OS would reclaim it's memory pages anyway. -- Bst rgrds, M.A.X.: Mechanical Artificial Xenomorph.

On Thu, Jan 02, 2003, Max Ischenko wrote:
Because garbage cycles can point at non-garbage; when the garbage is reclaimed, __del__() methods will run. You could argue that this is another reason against using __del__(), but since this is part of the way CPython works, I'm documenting it in my book. -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ "There are three kinds of lies: Lies, Damn Lies, and Statistics." --Disraeli

[Aahz]
Because garbage cycles can point at non-garbage; when the garbage is reclaimed, __del__() methods will run.
When cycles contain `__del__()', they are wholly added to gc.garbage if I understand the documentation correctly, and so, `__del__()' will not be run. -- François Pinard http://www.iro.umontreal.ca/~pinard

On Thursday 02 January 2003 03:47 pm, François Pinard wrote:
Yes, but that doesn't affect Aahz's argument -- consider, e.g.: class Nodel: pass class Hasdel: def __del__(self): print 'del(%s)'%self a, b, c = Nodel(), Nodel(), Nodel() a.x = b; b.x = c; c.x = a b.y = Hasdel() del a, b, c import gc # gc.collect() Here, the __del__ method is never run, but, if you uncomment the gc.collect call, then the __del__ method IS run -- just as Aahz said. Alex

[François Pinard]
When cycles contain `__del__()', they are wholly added to gc.garbage if I understand the documentation correctly, and so, `__del__()' will not be run.
True, but objects that are not *in* a cycle but that were kept alive because the cycle referenced them will have their __del__ methods run when the cycle is GC'ed. --Guido van Rossum (home page: http://www.python.org/~guido/)

Aahz wrote:
Documenting that you can call gc.collect() at the end is good; documenting that you should call it is not. I would expect that in many cases, it will be irrelevant whether __del__ is called at the end or not, as the system or the underlying libraries will reclaim whatever resources have been acquired. If you need to guarantee that __del__ is called at the end for all objects, you have probably much bigger problems in your application than that, and it is likely better to explicitly break any remaining cycles than to invoke gc.collect. Regards, Martin

On 02 January 2003, Aahz said:
As I recall (and this knowledge dates back to 1997 or so, so could well be obsolete), Perl does a full GC run at process exit time. In normal contexts this is irrelevant; I believe the justification was to clean up resources used by an embedded interpreter. Greg -- Greg Ward <gward@python.net> http://www.gerg.ca/

Embedded interpreters may do this, but the "main" interpreter may still not do this. The only time the "main" interpreter would benefit from this is if there are external resources that otherwise don't get cleaned up when the process exits (e.g. temp files). --Guido van Rossum (home page: http://www.python.org/~guido/)

[Greg Ward]
See http://tinyurl.com/41wy searching down for "Two-Phased Garbage Collection". Perl's mark-&-sweep phase runs when a thread terminates, which includes the main thread exiting, but isn't really aimed at that.
participants (8)
-
"Martin v. Löwis"
-
Aahz
-
Alex Martelli
-
Greg Ward
-
Guido van Rossum
-
Max Ischenko
-
pinard@iro.umontreal.ca
-
Tim Peters