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.

classification
Title: Add function to gc module to check if any reference cycles have been reclaimed.
Type: enhancement Stage: resolved
Components: Versions: Python 3.7
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: Kevin Mills, mark.dickinson
Priority: normal Keywords:

Created on 2017-02-27 20:35 by Kevin Mills, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg288668 - (view) Author: Kevin Mills (Kevin Mills) Date: 2017-02-27 20:35
The intro paragraph for the gc module's documentation says:

> Since the collector supplements the reference counting already used in Python, you can disable the collector if you are sure your program does not create reference cycles.

How would you ever be sure of that?

While you can prevent reference cycles in your own code, what about your dependencies? You'd have to look through the code of all of your dependencies and transitive dependencies (including the standard library) to verify that none introduce reference cycles. And then you'd have to redo that work when upgrading any of them.

I propose adding a function to the gc module that returns True if the gc has reclaimed at least one reference cycle in the course of the current program's execution.

With that, it would be possible to, a program could, before it exits, force a collection and then check if any reference cycles were found over the program's lifetime, and then the programmer could use that information to decide whether they can safely turn off the gc or not.

Obviously that wouldn't guarantee that you could safely turn of the gc (it's possible that garbage with reference cycles is created on other runs of the program) it would at least be some information.
msg288669 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2017-02-27 20:44
If I understand correctly, you can already achieve what you want by:

1. Disabling gc (with gc.disable()) at the beginning of your code, and possibly adding a `gc.collect()` immediately afterwards for good measure.
2. Doing a gc.collect() (and taking note of the return value) at the end of your code.
3. To be on the safe side, also check whether there's anything in `gc.garbage`.

If no reference cycles were created, `gc.collect()` will return `0`, and `gc.garbage` will be empty.
msg288670 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2017-02-27 20:47
An addendum: I'd note that avoiding reference cycles altogether is hard in modern-day Python. For example, any dynamically-created class creates a reference cycle between the class and its MRO:

>>> import gc
>>> gc.disable()
>>> gc.collect()
0
>>> class A(object):
...     pass
... 
>>> del A
>>> gc.collect()
6
msg288672 - (view) Author: Kevin Mills (Kevin Mills) Date: 2017-02-27 21:00
gc.disable() at the beginning and then analyzing the results of gc.collect() actually does do what I was wanting, thank you.

Reference cycles in and of themselves aren't the problem. It's only a problem if garbage contains reference cycles. In a normal program, a class wouldn't generally ever become garbage, so it wouldn't be a problem.
msg288700 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2017-02-28 08:56
> In a normal program, a class wouldn't generally ever become garbage,

Right; it's only really a problem with dynamically-created classes. Some parts of the standard library (like ctypes), generate such classes.

Okay to close this as rejected?
History
Date User Action Args
2022-04-11 14:58:43adminsetgithub: 73857
2017-03-01 08:46:15mark.dickinsonsetstatus: open -> closed
resolution: rejected
stage: resolved
2017-02-28 08:56:20mark.dickinsonsetmessages: + msg288700
2017-02-27 21:00:16Kevin Millssetmessages: + msg288672
2017-02-27 20:47:44mark.dickinsonsetmessages: + msg288670
2017-02-27 20:44:57mark.dickinsonsetnosy: + mark.dickinson
messages: + msg288669
2017-02-27 20:35:12Kevin Millscreate