Memory Management

Overview

Memory management in Python involves a private heap containing all Pythonobjects and data structures. The management of this private heap is ensuredinternally by thePython memory manager. The Python memory manager hasdifferent components which deal with various dynamic storage management aspects,like sharing, segmentation, preallocation or caching.

At the lowest level, a raw memory allocator ensures that there is enough room inthe private heap for storing all Python-related data by interacting with thememory manager of the operating system. On top of the raw memory allocator,several object-specific allocators operate on the same heap and implementdistinct memory management policies adapted to the peculiarities of every objecttype. For example, integer objects are managed differently within the heap thanstrings, tuples or dictionaries because integers imply different storagerequirements and speed/space tradeoffs. The Python memory manager thus delegatessome of the work to the object-specific allocators, but ensures that the latteroperate within the bounds of the private heap.

It is important to understand that the management of the Python heap isperformed by the interpreter itself and that the user has no control over it,even if they regularly manipulate object pointers to memory blocks inside thatheap. The allocation of heap space for Python objects and other internalbuffers is performed on demand by the Python memory manager through the Python/CAPI functions listed in this document.

To avoid memory corruption, extension writers should never try to operate onPython objects with the functions exported by the C library:malloc(),calloc(),realloc() andfree(). This will result in mixedcalls between the C allocator and the Python memory manager with fatalconsequences, because they implement different algorithms and operate ondifferent heaps. However, one may safely allocate and release memory blockswith the C library allocator for individual purposes, as shown in the followingexample:

PyObject*res;char*buf=(char*)malloc(BUFSIZ);/* for I/O */if(buf==NULL)returnPyErr_NoMemory();...DosomeI/Ooperationinvolvingbuf...res=PyBytes_FromString(buf);free(buf);/* malloc'ed */returnres;

In this example, the memory request for the I/O buffer is handled by the Clibrary allocator. The Python memory manager is involved only in the allocationof the bytes object returned as a result.

In most situations, however, it is recommended to allocate memory from thePython heap specifically because the latter is under control of the Pythonmemory manager. For example, this is required when the interpreter is extendedwith new object types written in C. Another reason for using the Python heap isthe desire toinform the Python memory manager about the memory needs of theextension module. Even when the requested memory is used exclusively forinternal, highly-specific purposes, delegating all memory requests to the Pythonmemory manager causes the interpreter to have a more accurate image of itsmemory footprint as a whole. Consequently, under certain circumstances, thePython memory manager may or may not trigger appropriate actions, like garbagecollection, memory compaction or other preventive procedures. Note that by usingthe C library allocator as shown in the previous example, the allocated memoryfor the I/O buffer escapes completely the Python memory manager.

See also

ThePYTHONMALLOC environment variable can be used to configurethe memory allocators used by Python.

ThePYTHONMALLOCSTATS environment variable can be used to printstatistics of thepymalloc memory allocator every time anew pymalloc object arena is created, and on shutdown.

Raw Memory Interface

The following function sets are wrappers to the system allocator. Thesefunctions are thread-safe, theGIL does notneed to be held.

Thedefault raw memory allocator usesthe following functions:malloc(),calloc(),realloc()andfree(); callmalloc(1) (orcalloc(1,1)) when requestingzero bytes.

New in version 3.4.

void*PyMem_RawMalloc(size_t n)

Allocatesn bytes and returns a pointer of typevoid* to theallocated memory, orNULL if the request fails.

Requesting zero bytes returns a distinct non-NULL pointer if possible, asifPyMem_RawMalloc(1) had been called instead. The memory will not havebeen initialized in any way.

void*PyMem_RawCalloc(size_t nelem, size_t elsize)

Allocatesnelem elements each whose size in bytes iselsize and returnsa pointer of typevoid* to the allocated memory, orNULL if therequest fails. The memory is initialized to zeros.

Requesting zero elements or elements of size zero bytes returns a distinctnon-NULL pointer if possible, as ifPyMem_RawCalloc(1,1) had beencalled instead.

New in version 3.5.

void*PyMem_RawRealloc(void *p, size_t n)

Resizes the memory block pointed to byp ton bytes. The contents willbe unchanged to the minimum of the old and the new sizes.

Ifp isNULL, the call is equivalent toPyMem_RawMalloc(n); else ifn is equal to zero, the memory block is resized but is not freed, and thereturned pointer is non-NULL.

Unlessp isNULL, it must have been returned by a previous call toPyMem_RawMalloc(),PyMem_RawRealloc() orPyMem_RawCalloc().

If the request fails,PyMem_RawRealloc() returnsNULL andpremains a valid pointer to the previous memory area.

voidPyMem_RawFree(void *p)

Frees the memory block pointed to byp, which must have been returned by aprevious call toPyMem_RawMalloc(),PyMem_RawRealloc() orPyMem_RawCalloc(). Otherwise, or ifPyMem_RawFree(p) has beencalled before, undefined behavior occurs.

Ifp isNULL, no operation is performed.

Memory Interface

The following function sets, modeled after the ANSI C standard, but specifyingbehavior when requesting zero bytes, are available for allocating and releasingmemory from the Python heap.

Thedefault memory allocator uses thepymalloc memory allocator.

Warning

TheGIL must be held when using thesefunctions.

Changed in version 3.6:The default allocator is now pymalloc instead of systemmalloc().

void*PyMem_Malloc(size_t n)

Allocatesn bytes and returns a pointer of typevoid* to theallocated memory, orNULL if the request fails.

Requesting zero bytes returns a distinct non-NULL pointer if possible, asifPyMem_Malloc(1) had been called instead. The memory will not havebeen initialized in any way.

void*PyMem_Calloc(size_t nelem, size_t elsize)

Allocatesnelem elements each whose size in bytes iselsize and returnsa pointer of typevoid* to the allocated memory, orNULL if therequest fails. The memory is initialized to zeros.

Requesting zero elements or elements of size zero bytes returns a distinctnon-NULL pointer if possible, as ifPyMem_Calloc(1,1) had been calledinstead.

New in version 3.5.

void*PyMem_Realloc(void *p, size_t n)

Resizes the memory block pointed to byp ton bytes. The contents will beunchanged to the minimum of the old and the new sizes.

Ifp isNULL, the call is equivalent toPyMem_Malloc(n); else ifnis equal to zero, the memory block is resized but is not freed, and thereturned pointer is non-NULL.

Unlessp isNULL, it must have been returned by a previous call toPyMem_Malloc(),PyMem_Realloc() orPyMem_Calloc().

If the request fails,PyMem_Realloc() returnsNULL andp remainsa valid pointer to the previous memory area.

voidPyMem_Free(void *p)

Frees the memory block pointed to byp, which must have been returned by aprevious call toPyMem_Malloc(),PyMem_Realloc() orPyMem_Calloc(). Otherwise, or ifPyMem_Free(p) has been calledbefore, undefined behavior occurs.

Ifp isNULL, no operation is performed.

The following type-oriented macros are provided for convenience. Note thatTYPE refers to any C type.

TYPE*PyMem_New(TYPE, size_t n)

Same asPyMem_Malloc(), but allocates(n*sizeof(TYPE)) bytes ofmemory. Returns a pointer cast toTYPE*. The memory will not havebeen initialized in any way.

TYPE*PyMem_Resize(void *p, TYPE, size_t n)

Same asPyMem_Realloc(), but the memory block is resized to(n*sizeof(TYPE)) bytes. Returns a pointer cast toTYPE*. On return,p will be a pointer to the new memory area, orNULL in the event offailure.

This is a C preprocessor macro;p is always reassigned. Save the originalvalue ofp to avoid losing memory when handling errors.

voidPyMem_Del(void *p)

Same asPyMem_Free().

In addition, the following macro sets are provided for calling the Python memoryallocator directly, without involving the C API functions listed above. However,note that their use does not preserve binary compatibility across Pythonversions and is therefore deprecated in extension modules.

  • PyMem_MALLOC(size)

  • PyMem_NEW(type,size)

  • PyMem_REALLOC(ptr,size)

  • PyMem_RESIZE(ptr,type,size)

  • PyMem_FREE(ptr)

  • PyMem_DEL(ptr)

Object allocators

The following function sets, modeled after the ANSI C standard, but specifyingbehavior when requesting zero bytes, are available for allocating and releasingmemory from the Python heap.

Thedefault object allocator uses thepymalloc memory allocator.

Warning

TheGIL must be held when using thesefunctions.

void*PyObject_Malloc(size_t n)

Allocatesn bytes and returns a pointer of typevoid* to theallocated memory, orNULL if the request fails.

Requesting zero bytes returns a distinct non-NULL pointer if possible, asifPyObject_Malloc(1) had been called instead. The memory will not havebeen initialized in any way.

void*PyObject_Calloc(size_t nelem, size_t elsize)

Allocatesnelem elements each whose size in bytes iselsize and returnsa pointer of typevoid* to the allocated memory, orNULL if therequest fails. The memory is initialized to zeros.

Requesting zero elements or elements of size zero bytes returns a distinctnon-NULL pointer if possible, as ifPyObject_Calloc(1,1) had been calledinstead.

New in version 3.5.

void*PyObject_Realloc(void *p, size_t n)

Resizes the memory block pointed to byp ton bytes. The contents will beunchanged to the minimum of the old and the new sizes.

Ifp isNULL, the call is equivalent toPyObject_Malloc(n); else ifnis equal to zero, the memory block is resized but is not freed, and thereturned pointer is non-NULL.

Unlessp isNULL, it must have been returned by a previous call toPyObject_Malloc(),PyObject_Realloc() orPyObject_Calloc().

If the request fails,PyObject_Realloc() returnsNULL andp remainsa valid pointer to the previous memory area.

voidPyObject_Free(void *p)

Frees the memory block pointed to byp, which must have been returned by aprevious call toPyObject_Malloc(),PyObject_Realloc() orPyObject_Calloc(). Otherwise, or ifPyObject_Free(p) has been calledbefore, undefined behavior occurs.

Ifp isNULL, no operation is performed.

Default Memory Allocators

Default memory allocators:

Configuration

Name

PyMem_RawMalloc

PyMem_Malloc

PyObject_Malloc

Release build

"pymalloc"

malloc

pymalloc

pymalloc

Debug build

"pymalloc_debug"

malloc + debug

pymalloc + debug

pymalloc + debug

Release build, without pymalloc

"malloc"

malloc

malloc

malloc

Debug build, without pymalloc

"malloc_debug"

malloc + debug

malloc + debug

malloc + debug

Legend:

Customize Memory Allocators

New in version 3.4.

PyMemAllocatorEx

Structure used to describe a memory block allocator. The structure hasfour fields:

Field

Meaning

void*ctx

user context passed as first argument

void*malloc(void*ctx,size_tsize)

allocate a memory block

void*calloc(void*ctx,size_tnelem,size_telsize)

allocate a memory block initializedwith zeros

void*realloc(void*ctx,void*ptr,size_tnew_size)

allocate or resize a memory block

voidfree(void*ctx,void*ptr)

free a memory block

Changed in version 3.5:ThePyMemAllocator structure was renamed toPyMemAllocatorEx and a newcalloc field was added.

PyMemAllocatorDomain

Enum used to identify an allocator domain. Domains:

PYMEM_DOMAIN_RAW

Functions:

PYMEM_DOMAIN_MEM

Functions:

PYMEM_DOMAIN_OBJ

Functions:

voidPyMem_GetAllocator(PyMemAllocatorDomain domain,PyMemAllocatorEx *allocator)

Get the memory block allocator of the specified domain.

voidPyMem_SetAllocator(PyMemAllocatorDomain domain,PyMemAllocatorEx *allocator)

Set the memory block allocator of the specified domain.

The new allocator must return a distinct non-NULL pointer when requestingzero bytes.

For thePYMEM_DOMAIN_RAW domain, the allocator must bethread-safe: theGIL is not held when theallocator is called.

If the new allocator is not a hook (does not call the previous allocator),thePyMem_SetupDebugHooks() function must be called to reinstall thedebug hooks on top on the new allocator.

voidPyMem_SetupDebugHooks(void)

Setup hooks to detect bugs in the Python memory allocator functions.

Newly allocated memory is filled with the byte0xCD (CLEANBYTE),freed memory is filled with the byte0xDD (DEADBYTE). Memory blocksare surrounded by “forbidden bytes” (FORBIDDENBYTE: byte0xFD).

Runtime checks:

On error, the debug hooks use thetracemalloc module to get thetraceback where a memory block was allocated. The traceback is onlydisplayed iftracemalloc is tracing Python memory allocations and thememory block was traced.

These hooks areinstalled by default ifPython is compiled in debugmode. ThePYTHONMALLOC environment variable can be used to installdebug hooks on a Python compiled in release mode.

Changed in version 3.6:This function now also works on Python compiled in release mode.On error, the debug hooks now usetracemalloc to get the tracebackwhere a memory block was allocated. The debug hooks now also checkif the GIL is held when functions ofPYMEM_DOMAIN_OBJ andPYMEM_DOMAIN_MEM domains are called.

Changed in version 3.8:Byte patterns0xCB (CLEANBYTE),0xDB (DEADBYTE) and0xFB (FORBIDDENBYTE) have been replaced with0xCD,0xDDand0xFD to use the same values than Windows CRT debugmalloc()andfree().

The pymalloc allocator

Python has apymalloc allocator optimized for small objects (smaller or equalto 512 bytes) with a short lifetime. It uses memory mappings called “arenas”with a fixed size of 256 KiB. It falls back toPyMem_RawMalloc() andPyMem_RawRealloc() for allocations larger than 512 bytes.

pymalloc is thedefault allocator of thePYMEM_DOMAIN_MEM (ex:PyMem_Malloc()) andPYMEM_DOMAIN_OBJ (ex:PyObject_Malloc()) domains.

The arena allocator uses the following functions:

  • VirtualAlloc() andVirtualFree() on Windows,

  • mmap() andmunmap() if available,

  • malloc() andfree() otherwise.

Customize pymalloc Arena Allocator

New in version 3.4.

PyObjectArenaAllocator

Structure used to describe an arena allocator. The structure hasthree fields:

Field

Meaning

void*ctx

user context passed as first argument

void*alloc(void*ctx,size_tsize)

allocate an arena of size bytes

voidfree(void*ctx,void*ptr,size_tsize)

free an arena

voidPyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)

Get the arena allocator.

voidPyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)

Set the arena allocator.

tracemalloc C API

New in version 3.7.

intPyTraceMalloc_Track(unsigned int domain, uintptr_t ptr, size_t size)

Track an allocated memory block in thetracemalloc module.

Return0 on success, return-1 on error (failed to allocate memory tostore the trace). Return-2 if tracemalloc is disabled.

If memory block is already tracked, update the existing trace.

intPyTraceMalloc_Untrack(unsigned int domain, uintptr_t ptr)

Untrack an allocated memory block in thetracemalloc module.Do nothing if the block was not tracked.

Return-2 if tracemalloc is disabled, otherwise return0.

Examples

Here is the example from sectionOverview, rewritten so that theI/O buffer is allocated from the Python heap by using the first function set:

PyObject*res;char*buf=(char*)PyMem_Malloc(BUFSIZ);/* for I/O */if(buf==NULL)returnPyErr_NoMemory();/* ...Do some I/O operation involving buf... */res=PyBytes_FromString(buf);PyMem_Free(buf);/* allocated with PyMem_Malloc */returnres;

The same code using the type-oriented function set:

PyObject*res;char*buf=PyMem_New(char,BUFSIZ);/* for I/O */if(buf==NULL)returnPyErr_NoMemory();/* ...Do some I/O operation involving buf... */res=PyBytes_FromString(buf);PyMem_Del(buf);/* allocated with PyMem_New */returnres;

Note that in the two examples above, the buffer is always manipulated viafunctions belonging to the same set. Indeed, it is required to use the samememory API family for a given memory block, so that the risk of mixing differentallocators is reduced to a minimum. The following code sequence contains twoerrors, one of which is labeled asfatal because it mixes two differentallocators operating on different heaps.

char*buf1=PyMem_New(char,BUFSIZ);char*buf2=(char*)malloc(BUFSIZ);char*buf3=(char*)PyMem_Malloc(BUFSIZ);...PyMem_Del(buf3);/* Wrong -- should be PyMem_Free() */free(buf2);/* Right -- allocated via malloc() */free(buf1);/* Fatal -- should be PyMem_Del()  */

In addition to the functions aimed at handling raw memory blocks from the Pythonheap, objects in Python are allocated and released withPyObject_New(),PyObject_NewVar() andPyObject_Del().

These will be explained in the next chapter on defining and implementing newobject types in C.