This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author belopolsky
Recipients belopolsky, georg.brandl, georg.brandl, jimjjewett
Date 2008-01-31.05:59:27
SpamBayes Score 3.9791316e-06
Marked as misclassified No
Message-id <1201759171.26.0.962353127517.issue1545463@psf.upfronthosting.co.za>
In-reply-to
Content
The problem still exists in 2.5.1.

The explanations given so far are not correct. With x.py as before (see 
attached):

>>> import sys, gc, x
creating X('new')
creating X('old')
>>> del x,sys.modules['x']
deleting X('old')
>>> gc.collect()
deleting X('new')
6

which shows that the cycles in x module are resolvable by GC.

The problem is not that there are uncollectable objects but that GC is 
ran on exit before x becomes dead.

>>> import sys, gc, x
creating X('new')
creating X('old')
>>> gc.set_debug(1)
>>> sys.exit()
gc: collecting generation 2...
gc: objects in each generation: 463 2034 0
gc: done.
deleting X('old')


Looking at the comments in Py_Finalize, it looks like GvR intended to 
run GC after destroying the modules, but it led to problems:
(from svn blame Python/pythonrun.c)
 32278 gvanrossum 
  9025      guido       /* Destroy all modules */
  8403      guido       PyImport_Cleanup();
  9025      guido 
 32278 gvanrossum       /* Collect final garbage.  This disposes of 
cycles created by
 34776    tim_one        * new-style class definitions, for example.
 34776    tim_one        * XXX This is disabled because it caused too 
many problems.  If
 34776    tim_one        * XXX a __del__ or weakref callback triggers 
here, Python code has
 34776    tim_one        * XXX a hard time running, because even the sys 
module has been
 34776    tim_one        * XXX cleared out (sys.stdout is gone, 
sys.excepthook is gone, etc).
 34776    tim_one        * XXX One symptom is a sequence of information-
free messages
 34776    tim_one        * XXX coming from threads (if a __del__ or 
callback is invoked,
 34776    tim_one        * XXX other threads can execute too, and any 
exception they encounter
 34776    tim_one        * XXX triggers a comedy of errors as subsystem 
after subsystem
 34776    tim_one        * XXX fails to find what it *expects* to find 
in sys to help report
 34776    tim_one        * XXX the exception and consequent unexpected 
failures).  I've also
 34776    tim_one        * XXX seen segfaults then, after adding print 
statements to the
 34776    tim_one        * XXX Python code getting called.
 34776    tim_one        */
 34776    tim_one #if 0
 32278 gvanrossum       PyGC_Collect();
 34776    tim_one #endif

Commenting out PyGC_Collect() seems like a too radical solution because  
no module referenced cycles get collected, not even those without 
__del__.

I have not tried it yet, but it looks like a possible solution is to 
call PyGC_Collect() at the end of _PyModule_Clear.
History
Date User Action Args
2008-01-31 05:59:31belopolskysetspambayes_score: 3.97913e-06 -> 3.9791316e-06
recipients: + belopolsky, georg.brandl, jimjjewett, gbrandl.historic
2008-01-31 05:59:31belopolskysetspambayes_score: 3.97913e-06 -> 3.97913e-06
messageid: <1201759171.26.0.962353127517.issue1545463@psf.upfronthosting.co.za>
2008-01-31 05:59:29belopolskylinkissue1545463 messages
2008-01-31 05:59:27belopolskycreate