Skip to content

Commit 11fdaee

Browse files
committed
Add the PYTHON_GC_THRESHOLD environment variable.
1 parent c00964e commit 11fdaee

File tree

5 files changed

+54
-0
lines changed

5 files changed

+54
-0
lines changed

Doc/using/cmdline.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,16 @@ conflict.
976976
.. versionadded:: 3.4
977977

978978

979+
.. envvar:: PYTHON_GC_THRESHOLD
980+
981+
Set the `threshold0` value for the garbage collector. This is the same
982+
as calling `gc.set_threshold(n)` where `n` is value of the variable. Using
983+
an empty value or the value "default" will cause the default threshold to be
984+
used.
985+
986+
.. versionadded:: 3.13
987+
988+
979989
.. envvar:: PYTHONMALLOC
980990

981991
Set the Python memory allocators and/or install debug hooks.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Add the `PYTHON_GC_THRESHOLD` environment variable. This can be used to set
2+
the `threshold0` value for the garbage collector, similar to calling
3+
`gc.set_threshold()`. If the value is empty or "default", the default
4+
threshold value is used.

Python/gc.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,31 @@ _PyGC_InitState(GCState *gcstate)
166166
#undef INIT_HEAD
167167
}
168168

169+
static void
170+
gc_set_threshold_from_env(PyInterpreterState *interp)
171+
{
172+
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
173+
const char *env = _Py_GetEnv(config->use_environment,
174+
"PYTHON_GC_THRESHOLD");
175+
if (env == NULL || strcmp(env, "default") == 0) {
176+
return;
177+
}
178+
int threshold = -1;
179+
if (_Py_str_to_int(env, &threshold) < 0) {
180+
return; // parse failed, silently ignore
181+
}
182+
if (threshold > 0) {
183+
interp->gc.young.threshold = threshold;
184+
}
185+
}
169186

170187
PyStatus
171188
_PyGC_Init(PyInterpreterState *interp)
172189
{
173190
GCState *gcstate = &interp->gc;
174191

192+
gc_set_threshold_from_env(interp);
193+
175194
gcstate->garbage = PyList_New(0);
176195
if (gcstate->garbage == NULL) {
177196
return _PyStatus_NO_MEMORY();

Python/gc_free_threading.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -838,12 +838,31 @@ _PyGC_InitState(GCState *gcstate)
838838
gcstate->young.threshold = 2000;
839839
}
840840

841+
static void
842+
gc_set_threshold_from_env(PyInterpreterState *interp)
843+
{
844+
const PyConfig *config = _PyInterpreterState_GetConfig(interp);
845+
const char *env = _Py_GetEnv(config->use_environment,
846+
"PYTHON_GC_THRESHOLD");
847+
if (env == NULL || strcmp(env, "default") == 0) {
848+
return;
849+
}
850+
int threshold = -1;
851+
if (_Py_str_to_int(env, &threshold) < 0) {
852+
return; // parse failed, silently ignore
853+
}
854+
if (threshold > 0) {
855+
interp->gc.young.threshold = threshold;
856+
}
857+
}
841858

842859
PyStatus
843860
_PyGC_Init(PyInterpreterState *interp)
844861
{
845862
GCState *gcstate = &interp->gc;
846863

864+
gc_set_threshold_from_env(interp);
865+
847866
gcstate->garbage = PyList_New(0);
848867
if (gcstate->garbage == NULL) {
849868
return _PyStatus_NO_MEMORY();

Python/initconfig.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ static const char usage_envvars[] =
342342
" on Python memory allocators. Use PYTHONMALLOC=debug to\n"
343343
" install debug hooks.\n"
344344
"PYTHONMALLOCSTATS: print memory allocator statistics\n"
345+
"PYTHON_GC_THRESHOLD: set threshold0 for the garbage collector. This\n"
346+
" threshold can also be set by gc.set_threshold().\n"
345347
"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n"
346348
" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request\n"
347349
" display of locale coercion and locale compatibility warnings\n"

0 commit comments

Comments
 (0)