From f8bf83b811cf54b4ce668bcda6043d14c4980f00 Mon Sep 17 00:00:00 2001
From: Sean <squahtx@users.noreply.github.com>
Date: Wed, 1 Sep 2021 11:55:31 +0100
Subject: [PATCH] Skip the final GC on shutdown to improve restart times
 (#10712)

Use `gc.freeze()` on exit to exclude all existing objects from the final GC.
In testing, this sped up shutdown by up to a few seconds.

`gc.freeze()` runs in constant time, so there is little chance of performance
regression.

Signed-off-by: Sean Quah <seanq@element.io>
---
 changelog.d/10712.feature | 1 +
 synapse/app/_base.py      | 7 +++++++
 2 files changed, 8 insertions(+)
 create mode 100644 changelog.d/10712.feature

diff --git a/changelog.d/10712.feature b/changelog.d/10712.feature
new file mode 100644
index 0000000000..d04db6f26f
--- /dev/null
+++ b/changelog.d/10712.feature
@@ -0,0 +1 @@
+Skip final GC at shutdown to improve restart performance.
diff --git a/synapse/app/_base.py b/synapse/app/_base.py
index 39e28aff9f..6fc14930d1 100644
--- a/synapse/app/_base.py
+++ b/synapse/app/_base.py
@@ -12,6 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+import atexit
 import gc
 import logging
 import os
@@ -403,6 +404,12 @@ async def start(hs: "HomeServer"):
         gc.collect()
         gc.freeze()
 
+    # Speed up shutdowns by freezing all allocated objects. This moves everything
+    # into the permanent generation and excludes them from the final GC.
+    # Unfortunately only works on Python 3.7
+    if platform.python_implementation() == "CPython" and sys.version_info >= (3, 7):
+        atexit.register(gc.freeze)
+
 
 def setup_sentry(hs):
     """Enable sentry integration, if enabled in configuration
-- 
GitLab