自定义内存分配器
3.4 新版功能.
PyMemAllocatorEx
用于描述内存块分配器的结构体。包含四个字段:
域 | 含义 |
---|---|
| 作为第一个参数传入的用户上下文 |
| 分配一个内存块 |
| 分配一个初始化为 0 的内存块 |
| 分配一个内存块或调整其大小 |
| 释放一个内存块 |
在 3.5 版更改: The PyMemAllocator
structure was renamed to PyMemAllocatorEx
and a new calloc
field was added.
PyMemAllocatorDomain
用来识别分配器域的枚举类。域有:
PYMEM_DOMAIN_RAW
函数
PYMEM_DOMAIN_MEM
函数
PYMEM_DOMAIN_OBJ
函数
void PyMem_GetAllocator
(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
获取指定域的内存块分配器。
void PyMem_SetAllocator
(PyMemAllocatorDomain domain, PyMemAllocatorEx *allocator)
设置指定域的内存块分配器。
当请求零字节时,新的分配器必须返回一个独特的非 NULL
指针。
对于 PYMEM_DOMAIN_RAW
域,分配器必须是线程安全的:当分配器被调用时,不持有 全局解释器锁 。
如果新的分配器不是钩子(不调用之前的分配器),必须调用 PyMem_SetupDebugHooks()
函数在新分配器上重新安装调试钩子。
void PyMem_SetupDebugHooks
(void)
设置检测 Python 内存分配器函数中错误的钩子。
新分配的内存由字节 0xCD
( CLEANBYTE
) 填充,释放的内存由字节 0xDD
( DEADBYTE
)填充。内存块被 “禁止字节” 包围( FORBIDDENBYTE
:字节 0xFD
)。
运行时检查:
检测对 API 的违反,例如:对用
PyMem_Malloc()
分配的缓冲区调用PyObject_Free()
。检测缓冲区起始位置前的写入(缓冲区下溢)。
检测缓冲区终止位置后的写入(缓冲区溢出)。
检测当调用
PYMEM_DOMAIN_OBJ
(如:PyObject_Malloc()
) 和PYMEM_DOMAIN_MEM
(如:PyMem_Malloc()
) 域的分配器函数时 GIL 已被保持。
在出错时,调试钩子使用 tracemalloc
模块来回溯内存块被分配的位置。只有当 tracemalloc
正在追踪 Python 内存分配,并且内存块被追踪时,才会显示回溯。
如果 Python 是在调试模式下编译的,这些钩子是 installed by default 。环境变量 PYTHONMALLOC
可以用来在发布模式编译的 Python 上安装调试钩子。
在 3.6 版更改: 这个函数现在也适用于以 发布模式编译的 Python。在出错时,调试钩子现在使用 tracemalloc
来回溯内存块被分配的位置。调试钩子现在也检查当 PYMEM_DOMAIN_OBJ
和 PYMEM_DOMAIN_MEM
域的函数被调用时,全局解释器锁是否被持有。
在 3.8 版更改: 字节模式 0xCB
(CLEANBYTE
)、 0xDB
(DEADBYTE
) 和 0xFB
(FORBIDDENBYTE
) 已被 0xCD
、 0xDD
和 0xFD
替代以使用与 Windows CRT 调试 malloc()
和 free()
相同的值。