From 2b0c5e24e6a026b02cb395282e88a8d33534848e Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 1 Sep 2026 16:59:58 +0200 Subject: [PATCH] Memory - GC freeze after startup to save CPU cycles and improve memory management (#4351) --- changedetectionio/flask_app.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py index 93937850e..d6922381f 100644 --- a/changedetectionio/flask_app.py +++ b/changedetectionio/flask_app.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import flask_login +import gc import hashlib import locale import os @@ -1095,6 +1096,15 @@ def changedetection_app(config=None, datastore_o=None): "snapshot reads are NOT confined to the watch data directory. " "This disables protection against path traversal via restored backups (GHSA-8757-69j2-hx56).") + # Memory/CPU management - + # Freeze the startup object graph into the "permanent generation" so that the cyclic + # garbage collector never traverses it again, this allows more of the app to swap into 'cold' RAM + if 'pytest' not in sys.modules and 'PYTEST_CURRENT_TEST' not in os.environ \ + and not strtobool(os.getenv('DISABLE_GC_FREEZE', 'no')): + gc.collect() + gc.freeze() + logger.debug(f"GC: froze {gc.get_freeze_count()} startup objects into the permanent generation") + # Start the async workers during app initialization # Can be overridden by ENV or use the default settings n_workers = int(os.getenv("FETCH_WORKERS", datastore.data['settings']['requests']['workers']))