Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-pyObject中的C扩展名为Py_DECREF,引用为0,但内存泄漏_Python_C_Python Extensions - Fatal编程技术网

Python-pyObject中的C扩展名为Py_DECREF,引用为0,但内存泄漏

Python-pyObject中的C扩展名为Py_DECREF,引用为0,但内存泄漏,python,c,python-extensions,Python,C,Python Extensions,这是我的密码 PyObject *dataPyParams = PyList_New(0); for (int i = 0; i < figdata.dataSetList.size(); i++) { PyObject *pyParams = PyList_New(0); for (int j = 0; j < figdata.dataSetList[i].size(); j++) { //std::cerr << figdata

这是我的密码

PyObject *dataPyParams = PyList_New(0);
for (int i = 0; i < figdata.dataSetList.size(); i++)
{
    PyObject *pyParams = PyList_New(0);
    for (int j = 0; j < figdata.dataSetList[i].size(); j++)
    {
        //std::cerr << figdata.dataSetList[i][j] << "data\n";
        auto temp = Py_BuildValue("f", figdata.dataSetList[i][j]);
        PyList_Append(pyParams,temp);
        Py_DECREF(temp);    
    }
    PyList_Append(dataPyParams, pyParams);
    Py_DECREF(pyParams);
    
}
Py_DECREF(dataPyParams);
PyObject*dataPyParams=PyList_New(0);
对于(int i=0;i
在本例中,您正在创建
浮动
列表
对象,这两个对象都有“自由列表”因此释放实际上并不会将它们返回给分配器,而是返回给一个简单的已分配但未使用的对象堆栈,
float
list
构造函数可以从中获取比向分配器请求更多内存更便宜的对象至少从分配器的角度来看,它们的一部分仍然被分配。您可以通过显式调用
PyGC_Collect()
(仅在中记录了副作用)来清除这些空闲列表,这可能允许将内存返回到操作系统,但同样,这也不能保证。您可能还需要尽管如此,Python仍完全有权无限期地保留大部分内存以满足未来的分配

简而言之,这可能不是内存泄漏。您可以使用更高级的内存分析工具(如果没有其他工具,Python本身将告诉您有关竞技场的使用情况,如果您在启动之前在您的环境中定义),但任务管理器只能看到操作系统所看到的内容,而不能看到Python本身在原始、大容量操作系统内存分配之上所进行的内部内存管理


在没有外部工具的情况下,一个简单的测试就是运行这个精确的代码(包括清理)多次。如果每次运行时内存都以固定的大幅度增加,那么是的,这可能是泄漏。但更有可能的是,您会发现第一次运行消耗了大量内存,但随后的运行只增加了很少或根本没有内存使用(有些可能会因为分配顺序和分配对齐问题而被使用,但这会非常小),因为他们正在利用释放的内存(在用户区,而不是操作系统),而不是要求操作系统提供更多内存。

如何测量内存?如何检查“内存未释放”?我认为可以用
PyList\u SetItem(pyParams,Py\u BuildValue(…)替换内部循环
因为它会引用。我在windows任务管理器中看到了它。这不可靠,也不足以测量实际内存泄漏。请尝试找到一些内存分析工具来帮助您测量实际分配和可用的。@AaronD.Marasco:只有在预先确定了
列表的大小,并且您正在填充现有的,但是n填充索引。他们使用了
PyList\u New(0)
,这就排除了这一点。出现了一个新问题,调用PyGC\u Collect()需要十多秒。python2。7@KeyboardMan:Python 2.7?WHYYYYY?!?它的生命已经结束,并且已经完全不受支持将近一年了。你为什么要为它编写新代码,更不用说新的扩展代码了(这比Python级代码的可移植性要低得多)?10秒看起来确实很长,但无法判断是什么导致了它。无论如何,普通代码不应该调用
PyGC_Collect()
在正常情况下,它会断断续续地分阶段运行,几乎不需要强制运行,我刚才提到它是强制清除自由列表的一种方式(主要目的的副作用)。