https://github.com/python/cpython/commit/b8dd06f1d6ee3b172c58d688f122b29bb2582f9a
commit: b8dd06f1d6ee3b172c58d688f122b29bb2582f9a
branch: main
author: Maik Schulze <[email protected]>
committer: corona10 <[email protected]>
date: 2026-11-07T07:21:14Z
summary:

gh-161420: Process mimalloc's delayed frees on every generic malloc again 
(gh-161533)

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-11-07-09-30-00.gh-issue-161420.mIdFre.rst
M Objects/mimalloc/page.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-11-07-09-30-00.gh-issue-161420.mIdFre.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-07-09-30-00.gh-issue-161420.mIdFre.rst
new file mode 100644
index 000000000000000..296a2267f397be0
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-11-07-09-30-00.gh-issue-161420.mIdFre.rst
@@ -0,0 +1,2 @@
+Restore ``mimalloc``'s previous behavior of processing delayed frees from other
+threads on every generic malloc call, reverting the change introduced in 
v2.2.2.
diff --git a/Objects/mimalloc/page.c b/Objects/mimalloc/page.c
index 4bce8ce76044cbe..2f26d04aaaa4d87 100644
--- a/Objects/mimalloc/page.c
+++ b/Objects/mimalloc/page.c
@@ -1071,6 +1071,12 @@ void* _mi_malloc_generic(mi_heap_t* heap, size_t size, 
bool zero, size_t huge_al
   }
   mi_assert_internal(mi_heap_is_initialized(heap));
 
+  // Process delayed frees from other threads (but skip contended ones).
+  // CPython: gh-161420 showed that calling _mi_heap_delayed_free_partial only
+  // once every 100 generic malloc calls led to high memory usage.
+  // To avoid this, we now process delayed frees on every generic malloc call 
again.
+  _mi_heap_delayed_free_partial(heap);
+
   // do administrative tasks every N generic mallocs
   if mi_unlikely(++heap->generic_count >= 100) {
     heap->generic_collect_count += heap->generic_count;
@@ -1078,9 +1084,6 @@ void* _mi_malloc_generic(mi_heap_t* heap, size_t size, 
bool zero, size_t huge_al
     // call potential deferred free routines
     _mi_deferred_free(heap, false);
 
-    // free delayed frees from other threads (but skip contended ones)
-    _mi_heap_delayed_free_partial(heap);
-
     // collect every once in a while (10000 by default)
     const long generic_collect = 
mi_option_get_clamp(mi_option_generic_collect, 1, 1000000L);
     if (heap->generic_collect_count >= generic_collect) {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to