-
-
Notifications
You must be signed in to change notification settings - Fork 34k
bpo-38379: Don't block collection of unreachable objects when some objects resurrect #16687
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
c4c6031 to
1e8cd07
Compare
tim-one
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This surprised me - nice! Left some comments, but am too fried to do a thorough review tonight. It's certainly on the intended track.
tim-one
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:Left more small comments. Higher level: does check_garbage() really serve a purpose anymore? It's doing 2/3rds of the work done by the new function just to see whether at least one thing has become directly reachable. Which the new function does anyway. Since the amount of trash is usually small, the relative expense of running the new function all the time is minor (it's not crawling over the entire generation, just the trash objects - which is usually an empty list!).
The fewer moving parts the better 😉
I very much agree with this! I did not have removed check_garbage because I wanted to make sure everything else looks fine before discussing about just doing the work every time (calling On the other hand To make sure our assumption is correct, I will run the pyperformance test suite :) (Although I think is not really necesary, but checking does not hurt), |
The bit-fiddling obfuscation in this module is depressing So repair all the remaining damage before |
Yep, modifying this code is surprisingly tricky as there are lots of contracts not precisely well documented and many optimization details make the thing even more obscure.
Unless we somehow introduce the call to |
|
I'm not looking to do less work than Looking at older versions of this code is good for the soul 😃 Neil's original was a joy to work with, subtle algorithms but coded in completely straightforward ways. I dare say I improved some on that, by introducing a concrete notion of "state", with well defined transitions that were trivial to implement and query. Pointers were always pointers, ints were always ints ... But the gc header struct had 3 members then (next, prev, and refcount copy). All the pain was introduced to get rid of the header's refcount member, and almost nothing was straightforward anymore. It's not a trade-off I would have made, but it's certainly defensible. In any case, the ubiquitous bit fiddling now also slowed the code. I don't at all mind making it a bit slower still to preserve some sanity 😜 |
|
@tim-one Ok, after some design iterations, I am more or less happy with the shape of Note: I have rebased to pick the latest |
3fbbc5c to
c27fa80
Compare
tim-one
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Left some last minor comments.
tim-one
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's good to ship. Nice work!
|
Thank you very much for the thorough review! :) |
…jects resurrect (pythonGH-16687) Currently if any finalizer invoked during garbage collection resurrects any object, the gc gives up and aborts the collection. Although finalizers are assured to only run once per object, this behaviour of the gc can lead to an ever-increasing memory situation if new resurrecting objects are allocated in every new gc collection. To avoid this, recompute what objects among the unreachable set need to be resurrected and what objects can be safely collected. In this way, resurrecting objects will not block the collection of other objects in the unreachable set.
…jects resurrect (pythonGH-16687) Currently if any finalizer invoked during garbage collection resurrects any object, the gc gives up and aborts the collection. Although finalizers are assured to only run once per object, this behaviour of the gc can lead to an ever-increasing memory situation if new resurrecting objects are allocated in every new gc collection. To avoid this, recompute what objects among the unreachable set need to be resurrected and what objects can be safely collected. In this way, resurrecting objects will not block the collection of other objects in the unreachable set.
…jects resurrect (pythonGH-16687) Currently if any finalizer invoked during garbage collection resurrects any object, the gc gives up and aborts the collection. Although finalizers are assured to only run once per object, this behaviour of the gc can lead to an ever-increasing memory situation if new resurrecting objects are allocated in every new gc collection. To avoid this, recompute what objects among the unreachable set need to be resurrected and what objects can be safely collected. In this way, resurrecting objects will not block the collection of other objects in the unreachable set.
https://bugs.python.org/issue38379