内存管理
¶
概述
¶
Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the
Python memory manager
. The Python memory manager has different 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 in the private heap for storing all Python-related data by interacting with the memory manager of the operating system. On top of the raw memory allocator, several object-specific allocators operate on the same heap and implement distinct memory management policies adapted to the peculiarities of every object type. For example, integer objects are managed differently within the heap than strings, tuples or dictionaries because integers imply different storage requirements and speed/space tradeoffs. The Python memory manager thus delegates some of the work to the object-specific allocators, but ensures that the latter operate within the bounds of the private heap.
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 they regularly manipulate 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.
To avoid memory corruption, extension writers should never try to operate on Python objects with the functions exported by the C library:
malloc()
,
calloc()
,
realloc()
and
free()
. This will result in mixed calls between the C allocator and the Python memory manager with fatal consequences, because they implement different algorithms and operate on different heaps. However, one may safely allocate and release memory blocks with the C library allocator for individual purposes, as shown in the following example:
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;
In this example, the memory request for the I/O buffer is handled by the C library allocator. The Python memory manager is involved only in the allocation of the bytes object returned as a result.
In most situations, however, it is recommended to allocate memory from the Python heap specifically because the latter is under control of the Python memory manager. For example, this is required when the interpreter is extended with new object types written in C. Another reason for using the Python heap is the desire to
inform
the Python memory manager about the memory needs of the extension module. Even when the requested memory is used exclusively for internal, highly specific purposes, delegating all memory requests to the Python memory manager causes the interpreter to have a more accurate image of its memory footprint as a whole. Consequently, under certain circumstances, the Python memory manager may or may not trigger appropriate actions, like garbage collection, memory compaction or other preventive procedures. Note that by using the C library allocator as shown in the previous example, the allocated memory for the I/O buffer escapes completely the Python memory manager.
Allocator Domains
¶
All allocating functions belong to one of three different “domains” (see also
PyMemAllocatorDomain
). These domains represent different allocation strategies and are optimized for different purposes. The specific details on how every domain allocates memory or what internal functions each domain calls is considered an implementation detail, but for debugging purposes a simplified table can be found at
here
. The APIs used to allocate and free a block of memory must be from the same domain. For example,
PyMem_Free()
must be used to free memory allocated using
PyMem_Malloc()
.
The three allocation domains are:
-
Raw domain: intended for allocating memory for general-purpose memory buffers where the allocation
must
go to the system allocator or where the allocator can operate without the
GIL
. The memory is requested directly from the system. See
原生内存接口
.
-
“Mem” domain: intended for allocating memory for Python buffers and general-purpose memory buffers where the allocation must be performed with the
GIL
held. The memory is taken from the Python private heap. See
内存接口
.
-
Object domain: intended for allocating memory for Python objects. The memory is taken from the Python private heap. See
对象分配器
.
注意
The
free-threaded
build requires that only Python objects are allocated using the “object” domain and that all Python objects are allocated using that domain. This differs from the prior Python versions, where this was only a best practice and not a hard requirement.
For example, buffers (non-Python objects) should be allocated using
PyMem_Malloc()
,
PyMem_RawMalloc()
,或
malloc()
, but not
PyObject_Malloc()
.
见
Memory Allocation APIs
.
原生内存接口
¶
The following function sets are wrappers to the system allocator. These functions are thread-safe, the
GIL
不需要保持。
The
默认原生内存分配器
使用下列函数:
malloc()
,
calloc()
,
realloc()
and
free()
; call
malloc(1)
(或
calloc(1, 1)
) 当请求 0 字节时。
Added in version 3.4.