Python Python (private heap) Python (Python memory manager) Python (sharing) (segmentation) (preallocation) (caching)
(raw memory allocator) Python /Python
It is important to understand that the management of the Python heap is performed by the interpreter itself and that the user has no control over it, even if she regularly manipulates object pointers to memory blocks inside that heap. The allocation of heap space for Python objects and other internal buffers is performed on demand by the Python memory manager through the Python/C API functions listed in this document.
Python C : malloc() calloc() realloc() free() C Python C Python C :
PyObject *res;
char *buf = (char *) malloc(BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
...Do some I/O operation involving buf...
res = PyBytes_FromString(buf);
free(buf); /* malloc'ed */
return res;
I/O C Python
Python Python Python C Python Python Python Python C I/O Python
: malloc(), calloc(), realloc(), free()
0 malloc(1) ( calloc(1, 1))
3.4 .
-
void*
PyMem_RawCalloc(size_t nelem, size_t elsize) elsize nelem
void*NULL0
PyMem_RawCalloc(1, 1)NULL3.5 .
-
void*
PyMem_RawRealloc(void *p, size_t n) p n
p NULL
PyMem_RawMalloc(n)n NULLp NULL p
PyMem_RawMalloc(),PyMem_RawRealloc(),PyMem_RawCalloc()PyMem_RawRealloc()NULL p
-
void
PyMem_RawFree(void *p) Frees the memory block pointed to by p, which must have been returned by a previous call to
PyMem_RawMalloc(),PyMem_RawRealloc()orPyMem_RawCalloc(). Otherwise, or ifPyMem_RawFree(p)has been called before, undefined behavior occurs.p NULL
Python ANSI C 0 :
3.6 : malloc() pymalloc
-
void*
PyMem_Calloc(size_t nelem, size_t elsize) elsize nelem
void*NULL0
PyMem_Calloc(1, 1)NULL3.5 .
-
void*
PyMem_Realloc(void *p, size_t n) p n
p NULL
PyMem_Malloc(n)n NULLp NULL p
PyMem_Malloc(),PyMem_Realloc()PyMem_Calloc()PyMem_Realloc()NULL p
-
void
PyMem_Free(void *p) p p
PyMem_Malloc()PyMem_Realloc()PyMem_Calloc()PyMem_Free(p)p NULL
TYPE C
-
TYPE*
PyMem_New(TYPE, size_t n) PyMem_Malloc()(n * sizeof(TYPE))TYPE*
-
TYPE*
PyMem_Resize(void *p, TYPE, size_t n) PyMem_Realloc()(n * sizeof(TYPE))TYPE*p NULLC p p
C API Python Python
PyMem_MALLOC(size)PyMem_NEW(type, size)PyMem_REALLOC(ptr, size)PyMem_RESIZE(ptr, type, size)PyMem_FREE(ptr)PyMem_DEL(ptr)
Object allocators
Python ANSI C 0 :
-
void*
PyObject_Malloc(size_t n) n
void*NULLRequesting zero bytes returns a distinct non-NULL pointer if possible, as if
PyObject_Malloc(1)had been called instead. The memory will not have been initialized in any way.
-
void*
PyObject_Calloc(size_t nelem, size_t elsize) elsize nelem
void*NULLRequesting zero elements or elements of size zero bytes returns a distinct non-NULL pointer if possible, as if
PyObject_Calloc(1, 1)had been called instead.3.5 .
-
void*
PyObject_Realloc(void *p, size_t n) p n
If p is NULL, the call is equivalent to
PyObject_Malloc(n); else if n is equal to zero, the memory block is resized but is not freed, and the returned pointer is non-NULL.Unless p is NULL, it must have been returned by a previous call to
PyObject_Malloc(),PyObject_Realloc()orPyObject_Calloc().If the request fails,
PyObject_Realloc()returns NULL and p remains a valid pointer to the previous memory area.
-
void
PyObject_Free(void *p) Frees the memory block pointed to by p, which must have been returned by a previous call to
PyObject_Malloc(),PyObject_Realloc()orPyObject_Calloc(). Otherwise, or ifPyObject_Free(p)has been called before, undefined behavior occurs.p NULL
3.4 .
-
PyMemAllocatorEx 4:
void *ctxvoid* malloc(void *ctx, size_t size)void* calloc(void *ctx, size_t nelem, size_t elsize)0 void* realloc(void *ctx, void *ptr, size_t new_size)void free(void *ctx, void *ptr)3.5 :
PyMemAllocatorPyMemAllocatorExcalloc
-
void
PyMem_GetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
-
void
PyMem_SetAllocator(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator) -
0 NULL
-
void
PyMem_SetupDebugHooks(void) Python
0xCB0xDB:
- API :
PyMem_Malloc()PyObject_Free() - ()
- ()
- Check that the GIL is held when
allocator functions of
PYMEM_DOMAIN_OBJ(ex:PyObject_Malloc()) andPYMEM_DOMAIN_MEM(ex:PyMem_Malloc()) domains are called
On error, the debug hooks use the
tracemallocmodule to get the traceback where a memory block was allocated. The traceback is only displayed iftracemallocis tracing Python memory allocations and the memory block was traced.These hooks are installed by default if Python is compiled in debug mode. The
PYTHONMALLOCenvironment variable can be used to install debug hooks on a Python compiled in release mode.3.6 : This function now also works on Python compiled in release mode. On error, the debug hooks now use
tracemallocto get the traceback where a memory block was allocated. The debug hooks now also check if the GIL is held when functions ofPYMEM_DOMAIN_OBJandPYMEM_DOMAIN_MEMdomains are called.- API :
pymalloc
Python (512) pymalloc pymalloc 256 KB "" 512 PyMem_RawMalloc() PyMem_RawRealloc()
pymalloc is the default allocator of the PYMEM_DOMAIN_MEM (ex:
PyMem_Malloc()) and PYMEM_DOMAIN_OBJ (ex:
PyObject_Malloc()) domains.
:
- Windows
VirtualAlloc()VirtualFree() mmap()munmap()-
malloc()free()
pymalloc
3.4 .
-
PyObjectArenaAllocator 3:
void *ctxvoid* alloc(void *ctx, size_t size)size void free(void *ctx, size_t size, void *ptr)
-
PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator)
-
PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator)
PyObject *res;
char *buf = (char *) PyMem_Malloc(BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyBytes_FromString(buf);
PyMem_Free(buf); /* allocated with PyMem_Malloc */
return res;
:
PyObject *res;
char *buf = PyMem_New(char, BUFSIZ); /* for I/O */
if (buf == NULL)
return PyErr_NoMemory();
/* ...Do some I/O operation involving buf... */
res = PyBytes_FromString(buf);
PyMem_Del(buf); /* allocated with PyMem_New */
return res;
API (Fatal)
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() */
Python PyObject_New() PyObject_NewVar() PyObject_Del() Python
C