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
Move _Py_RefTotal to PyInterpreterState #102304
Comments
From #100227 (comment):
|
Alternately, from #100227 (comment):
|
I vote to make it atomic instead of per interpreter. I use this while debugging refleaks and making it per interp will effectively make it impossible to use. This is only used in debug builds so I am not too much concerned about performance. |
Do you modify |
* main: pythongh-102304: Consolidate Direct Usage of _Py_RefTotal (pythongh-102514) pythongh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Objects/) (python#102218) pythongh-102507 Remove invisible pagebreak characters (python#102531) pythongh-102515: Remove unused imports in the `Lib/` directory (python#102516) Remove or update bitbucket links (pythonGH-101963) pythongh-101100: Fix sphinx warnings in `zipapp` and `zipfile` modules (python#102526) pythonGH-102397: Fix segfault from race condition in signal handling (python#102399) Fix style in argparse.rst (python#101733) Post 3.12.0a6 fix typo in async generator code field name `ag_code` (python#102448) Python 3.12.0a6
I do that sometimes though that's not important. With this change is |
We would definitely make sure that happens, since that's basically how it works now, but I don't think I did that in my branch. Doing so means that we'd have to track leaks during each subinterpreter finalization, which I don't think I've been doing. That's manageable though. |
Have you tried making it atomic? It will preserve all existing behavior like working after runtime is finalized and would work for per interpreter GIL. This is important as otherwise we'll lose the ability to monitor refleaks across multiple runtime initializations . |
I haven't looked at the implementation but I think there might be complications in this because some of the things at startup happens when GIL is not created so might need some special casing to get right. |
I started but haven't gotten back to it. Regardless, I think it is worth having a per-interpreter reftotal for the following reasons:
What do you mean by this? Are you talking about objects that don't get freed during interpreter finalization? If so, how is multiple runtime initializations an exceptional case?
I'm not sure I follow. Please elaborate on how the GIL relates to tracking refleaks for each interpreter? Or are you talking about something else? |
We need to make sure that the counter remains valid even after the runtime is finalized. If there are multiple runtime finalizations we need to continue using the old counter value and not initialize it to zero as we'll lose the old value. This is what I meant. |
While working on #101696 I noticed that the type cache is initialized before the gil is created which increfs |
@kumaraditya303, FYI, I've updated gh-102543 to preserve the reftotal across multiple runtime init/fini cycles. I'm still not sure what the value of that is, though. The only case I can imagine is where you have a leak during the first runtime instance but not in the second and somehow you only check for leaks after the second. In my mind you'd check for leaks after each finalization. In fact, that's exactly what happens if with (Regardless, I certainly concede that there are possible use cases of which I'm not aware! |
@kumaraditya303, with the above in mind, do you have any objections to gh-102543 and to using Note that if you're on board then move to per-interpreter (gh-102545) shouldn't be an issue. |
No objections to this. You can proceed with this |
Thanks! Your feedback was super helpful. |
The essentially eliminates the global variable, with the associated benefits. This is also a precursor to isolating this bit of state to PyInterpreterState. Folks that currently read _Py_RefTotal directly would have to start using _Py_GetGlobalRefTotal() instead. #102304
Moving it valuable with a per-interpreter GIL. However, it is also useful without one, since it allows us to identify refleaks within a single interpreter or where references are escaping an interpreter. This becomes more important as we move the obmalloc state to PyInterpreterState. #102304
(See gh-100227.)
_Py_RefTotal
holds the current global total number of refcounts. It only exists ifPy_REF_DEBUG
is defined (implied byPy_DEBUG
). It is exposed bysys.gettotalrefcount()
and set byPy_INCREF()
,Py_DECREF()
, etc. and_Py_NewReference()
.Modications to
_Py_RefTotal
are currently protected by the GIL so it should be moved toPyInterpreterState
. For various aspects of compatibility, it makes sense to keep the_Py_RefTotal
symbol around (and correct) and keep returning the global total fromsys.gettotalrefcount()
.Also,
_Py_RefTotal
is used by stable ABI extensions only wherePy_REF_DEBUG
is defined (unlikely) and only where built against 3.9 or earlier. Just in case, though, we must still keep the global variable around, so any solution here must respect that.Linked PRs
The text was updated successfully, but these errors were encountered: