我正在阅读 documentation for Memory Management in Python C extensions ,据我所知,似乎没有太多理由使用 malloc
而不是 PyMem_Malloc
。假设我想分配一个不暴露给 Python 源代码的数组,并将存储在一个将被垃圾收集的对象中。有什么理由要使用 malloc
吗?
最佳答案
编辑:混合PyMem_Malloc
和PyObject_Malloc
更正;它们是两个不同的调用。
没有 PYMALLOC_DEBUG
宏激活,PyMem_Malloc
是 libc 的 malloc()
的别名,有一个特殊情况:调用 PyMem_Malloc
分配零字节将返回非 NULL 指针,而 malloc(zero_bytes) 可能返回 NULL 值或引发系统错误 (source code reference):
/* malloc. Note that nbytes==0 tries to return a non-NULL pointer, distinct
- from all other currently live pointers. This may not be possible. */
此外,关于 pymem.h
header file 的咨询说明:
Never mix calls to PyMem_ with calls to the platform malloc/realloc/ calloc/free. For example, on Windows different DLLs may end up using different heaps, and if you use PyMem_Malloc you'll get the memory from the heap used by the Python DLL; it could be a disaster if you free()'ed that directly in your own extension. Using PyMem_Free instead ensures Python can return the memory to the proper heap. As another example, in PYMALLOC_DEBUG mode, Python wraps all calls to all PyMem_ and PyObject_ memory functions in special debugging wrappers that add additional debugging info to dynamic memory blocks. The system routines have no idea what to do with that stuff, and the Python wrappers have no idea what to do with raw blocks obtained directly by the system routines then.
然后,PyMem_Malloc
PyObject_Malloc
中有一些 Python 特定的调整,该函数不仅用于 C 扩展,还用于所有动态分配在运行 Python 程序时,例如 100*234
、str(100)
或 10 + 4j
:
>>> id(10 + 4j)
139721697591440
>>> id(10 + 4j)
139721697591504
>>> id(10 + 4j)
139721697591440
前面的 complex()
实例是分配在专用池上的小对象。
使用 的小对象(<256 字节)分配 PyMem_Malloc
PyObject_Malloc
非常有效,因为它是从池中完成的 8 字节对齐 block ,现有每个 block 大小一个池。还有用于更大分配的 Pages 和 Arenas block 。
这条评论在source code解释了如何优化 PyObject_Malloc
调用:
/*
* The basic blocks are ordered by decreasing execution frequency,
* which minimizes the number of jumps in the most common cases,
* improves branching prediction and instruction scheduling (small
* block allocations typically result in a couple of instructions).
* Unless the optimizer reorders everything, being too smart...
*/
池、页面和竞技场是旨在减少 external memory fragmentation 的优化。长时间运行的 Python 程序。
查看 the source code有关 Python 内存内部结构的完整详细文档。
关于python - 有什么理由在 PyMem_Malloc 上使用 malloc 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4823054/