Python NumPy C API扩展导致内存使用过度
我已经为NumPy编写了一个C扩展来加速我的一些计算,但是随着我反复调用这个函数,我的内存使用率越来越高。我已将函数缩减为一个最小示例:Python NumPy C API扩展导致内存使用过度,python,c,numpy,python-c-api,Python,C,Numpy,Python C Api,我已经为NumPy编写了一个C扩展来加速我的一些计算,但是随着我反复调用这个函数,我的内存使用率越来越高。我已将函数缩减为一个最小示例: PyObject* memory_test_function(PyObject* self, PyObject* args) { PyArrayObject *ang; int i; if (!PyArg_ParseTuple(args, "O", &ang)) return NULL; int L0 = (int)
PyObject* memory_test_function(PyObject* self, PyObject* args)
{
PyArrayObject *ang;
int i;
if (!PyArg_ParseTuple(args, "O", &ang)) return NULL;
int L0 = (int) PyArray_DIMS(ang)[0];
// ballooning memory usage
npy_intp final_out_dims[2] = {L0,1};
PyObject *output_array;
output_array = PyArray_SimpleNew(2, final_out_dims, NPY_FLOAT64);
Py_INCREF(output_array);
for (i=0;i<L0;i++)
{
*(double *)PyArray_GETPTR2(output_array,i,0) =
tan(*(double *)PyArray_GETPTR2(ang,i,0));
}
return PyArray_Return(output_array);
/* constant memory usage
double sum=0.0;
for (i=0;i<L0;i++) sum+=tan(*(double *)PyArray_GETPTR2(ang,i,0));
return PyFloat_FromDouble(sum); */
}
PyObject*内存测试函数(PyObject*self,PyObject*args)
{
PyArrayObject*ang;
int i;
if(!PyArg_ParseTuple(args,“O”&ang))返回NULL;
int L0=(int)PyArray_DIMS(ang)[0];
//不断膨胀的内存使用率
npy_intp final_out_dims[2]={L0,1};
PyObject*输出_数组;
输出数组=PyArray\u SimpleNew(2,最终输出dims,NPY\u浮点64);
Py_增量(输出_数组);
对于引擎盖下的(i=0;iPyArray\u SimpleNew
调用(可能间接)\u Py\u NewReference
。此函数将新创建引用的引用计数设置为1
随后的Py\u incremf
将ref计数增加到2,从而确保Python永远不会释放此对象,即使对它的所有引用都不再存在,因为它的引用计数永远不会下降到0
Py\u INCREF
调用是不必要的,因为您没有与任何其他对象共享引用,您只是在本地使用它,然后将其传递给调用方。我对Python C API一无所知,但我怀疑您的Py\u INCREF
调用:您没有与任何其他对象共享引用e、 您正在将其传递给调用者。因此,要么根本不增加引用计数,要么在本地使用完它后减少引用计数。您可以通过gc.get\u referers()
在调用代码中检查这一点。如果我是对的,如果您没有制作任何其他副本,它将返回2,并且应该返回1(您也可以通过Py\u REFCNT(output\u array)
在您的C代码中检查它)。事实上,这解决了问题!我不知道传递它不需要增量。我很乐意接受这个答案。