Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Python's small object allocator (``obmalloc.c``) now allows (no more than) one empty arena to remain available for immediate reuse, without returning it to the OS. This prevents thrashing in simple loops where an arena could be created and destroyed anew on each iteration.
9 changes: 7 additions & 2 deletions Objects/obmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1758,7 +1758,12 @@ pymalloc_free(void *ctx, void *p)
/* All the rest is arena management. We just freed
* a pool, and there are 4 cases for arena mgmt:
* 1. If all the pools are free, return the arena to
* the system free().
* the system free(). Except if this is the last
* arena in the list, keep it to avoid thrashing:
* keeping one wholly free arena in the list avoids
* pathological cases where a simple loop would
* otherwise provoke needing to allocate and free an
* arena on every iteration. See bpo-37257.
* 2. If this is the only free pool in the arena,
* add the arena back to the `usable_arenas` list.
* 3. If the "next" arena has a smaller count of free
Expand All @@ -1767,7 +1772,7 @@ pymalloc_free(void *ctx, void *p)
* nfreepools.
* 4. Else there's nothing more to do.
*/
if (nf == ao->ntotalpools) {
if (nf == ao->ntotalpools && ao->nextarena != NULL) {
/* Case 1. First unlink ao from usable_arenas.
*/
assert(ao->prevarena == NULL ||
Expand Down