Can Python garbage collection guarantee the restoration of circular reference objects under any circumstances?

This question is a continuation of the question I asked earlier: Python delegation pattern - How to avoid circular reference? After reading the answers, I decided to clarify my question, but it was suggested to publish it separately.

Here:

  • An excerpt in Python docs (reproduced below) states that garbage collection is not guaranteed for circular referencing objects. The post I found here offers the same thing. But the answers to my previous question do not agree. So, did I misunderstand this passage or the details that I missed?
  • I suppose, using a weak link, as pointed out by Alex Martelli, the answer to the question Should I worry about Python circular links? , would avoid the overhead of garbage collection links to the objects mentioned in his answer entirely? If so, how does it work?

Relevant Python docs that suggest inconsistent after going from a Python doc:

Implementation details of CPython: CPython currently uses a link counting scheme with an (optionally) delayed detection of cyclically related garbage that collects most objects as soon as they become unavailable, but garbage collection containing round links is not guaranteed . See the gc module documentation for information on controlling cyclic garbage collection. Other implementations act differently, and CPython may change. Do not depend on the immediate completion of objects when they become inaccessible (for example: always close files).

Walkthrough in its original form can be found here: http://docs.python.org/reference/datamodel.html Bold is mine.

Thanks in advance for any answers.

+3
source share
2 answers

I believe that the most important reason that objects with circular references are not guaranteed is because, by design, Python never collects objects with circular references if they define the __del__ method. There is a fairly simple simple reason :

Python does not automatically collect such loops because, as a rule, Python cannot guess the safe order of the __del__() methods.

I do not want to say that this is the only reason why unreachable objects with circular links cannot be detected. There are probably some unusual situations that can disrupt GC cycle detection mechanisms. But if you do not define __del__ for one of your objects, you are probably all right. Just don’t worry about it and use the advanced GC debugging options if you see performance issues.

+2
source

When he says that he doesn’t guarantee getting circular links, that’s exactly what it means. Whenever you are data structures containing circular references, the reference count will always be nonzero, which means that reference counting is not enough to decide when to delete them. On the other hand, finding all the circular links after reaching the end of each area will take a long time - at least. This involves analyzing the relationships of all objects with a non-zero number of links.

However, I do not expect you to have a problem with this in general. For a light script, you can simply ignore it. For others, you still have to do some cleaning work at the end of the scope (closing a file or even deleting a circular link), as it would in C, for example, but it's still not as drunk as C.

If this becomes a problem, simply remove the circular reference before you finish with each data object.

+1
source

Source: https://habr.com/ru/post/1412714/


All Articles