mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
GH-140638: Add a GC "candidates" stat (GH-141814)
This commit is contained in:
parent
425fd85ca3
commit
227b9d326e
7 changed files with 50 additions and 20 deletions
|
|
@ -100,6 +100,7 @@ struct collection_state {
|
|||
int skip_deferred_objects;
|
||||
Py_ssize_t collected;
|
||||
Py_ssize_t uncollectable;
|
||||
Py_ssize_t candidates;
|
||||
Py_ssize_t long_lived_total;
|
||||
struct worklist unreachable;
|
||||
struct worklist legacy_finalizers;
|
||||
|
|
@ -975,15 +976,12 @@ static bool
|
|||
update_refs(const mi_heap_t *heap, const mi_heap_area_t *area,
|
||||
void *block, size_t block_size, void *args)
|
||||
{
|
||||
struct collection_state *state = (struct collection_state *)args;
|
||||
PyObject *op = op_from_block(block, args, false);
|
||||
if (op == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (gc_is_alive(op)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exclude immortal objects from garbage collection
|
||||
if (_Py_IsImmortal(op)) {
|
||||
op->ob_tid = 0;
|
||||
|
|
@ -991,6 +989,11 @@ update_refs(const mi_heap_t *heap, const mi_heap_area_t *area,
|
|||
gc_clear_unreachable(op);
|
||||
return true;
|
||||
}
|
||||
// Marked objects count as candidates, immortals don't:
|
||||
state->candidates++;
|
||||
if (gc_is_alive(op)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Py_ssize_t refcount = Py_REFCNT(op);
|
||||
if (_PyObject_HasDeferredRefcount(op)) {
|
||||
|
|
@ -1911,7 +1914,8 @@ handle_resurrected_objects(struct collection_state *state)
|
|||
static void
|
||||
invoke_gc_callback(PyThreadState *tstate, const char *phase,
|
||||
int generation, Py_ssize_t collected,
|
||||
Py_ssize_t uncollectable, double duration)
|
||||
Py_ssize_t uncollectable, Py_ssize_t candidates,
|
||||
double duration)
|
||||
{
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
|
||||
|
|
@ -1925,10 +1929,11 @@ invoke_gc_callback(PyThreadState *tstate, const char *phase,
|
|||
assert(PyList_CheckExact(gcstate->callbacks));
|
||||
PyObject *info = NULL;
|
||||
if (PyList_GET_SIZE(gcstate->callbacks) != 0) {
|
||||
info = Py_BuildValue("{sisnsnsd}",
|
||||
info = Py_BuildValue("{sisnsnsnsd}",
|
||||
"generation", generation,
|
||||
"collected", collected,
|
||||
"uncollectable", uncollectable,
|
||||
"candidates", candidates,
|
||||
"duration", duration);
|
||||
if (info == NULL) {
|
||||
PyErr_FormatUnraisable("Exception ignored while "
|
||||
|
|
@ -2372,7 +2377,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
|
|||
GC_STAT_ADD(generation, collections, 1);
|
||||
|
||||
if (reason != _Py_GC_REASON_SHUTDOWN) {
|
||||
invoke_gc_callback(tstate, "start", generation, 0, 0, 0);
|
||||
invoke_gc_callback(tstate, "start", generation, 0, 0, 0, 0.0);
|
||||
}
|
||||
|
||||
if (gcstate->debug & _PyGC_DEBUG_STATS) {
|
||||
|
|
@ -2427,6 +2432,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
|
|||
stats->collected += m;
|
||||
stats->uncollectable += n;
|
||||
stats->duration += duration;
|
||||
stats->candidates += state.candidates;
|
||||
|
||||
GC_STAT_ADD(generation, objects_collected, m);
|
||||
#ifdef Py_STATS
|
||||
|
|
@ -2445,7 +2451,7 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
|
|||
}
|
||||
|
||||
if (reason != _Py_GC_REASON_SHUTDOWN) {
|
||||
invoke_gc_callback(tstate, "stop", generation, m, n, duration);
|
||||
invoke_gc_callback(tstate, "stop", generation, m, n, state.candidates, duration);
|
||||
}
|
||||
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue