python - 有什么理由在 PyMem_Malloc 上使用 malloc 吗?

标签 python c malloc python-c-extension

我正在阅读 documentation for Memory Management in Python C extensions ,据我所知,似乎没有太多理由使用 malloc 而不是 PyMem_Malloc。假设我想分配一个不暴露给 Python 源代码的数组,并将存储在一个将被垃圾收集的对象中。有什么理由要使用 malloc 吗?

最佳答案

编辑:混合PyMem_MallocPyObject_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*234str(100)10 + 4j:

>>> id(10 + 4j)
139721697591440
>>> id(10 + 4j)
139721697591504
>>> id(10 + 4j)
139721697591440

前面的 complex() 实例是分配在专用池上的小对象。

使用 PyMem_Malloc 的小对象(<256 字节)分配 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/

相关文章:

c - C中二维数组声明的歧义

python - 如何在字典中存储一组图像,并使用python opencv检索它

python - 选择每组的最大值

Python:变量不通过函数累积传递

python - 如果我使用 QT For Windows,我的应用程序会在 Linux/Mac/Windows 上运行良好吗?

c - C 中的 malloc 字符串

c - unistd.h 的 `l` 中的 `lseek` 是什么意思?

子进程和父进程之间的通信

c - 我正在尝试创建一个在输入\n 后计算行数的程序。我究竟做错了什么?

c - 在Linux(RedHat)中,C函数malloc_stats()与/proc/<pid>/stat常驻内存大小相比显示不同的值