我已经为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) 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); */
}
这个问题似乎是由创建输出数组引起的,因为仅仅返回一个float而不创建array对象在内存中是恒定的。我怀疑INCREF/DECREF有问题,但我认为我做的一切都是正确的。重复调用这个函数(大约一百万次)会使内存使用率随着时间线性增加,这让我觉得有些东西没有被正确地垃圾收集。手动使用gc
没有帮助。如果有什么明显的遗漏请告诉我!你知道吗
PyArray_SimpleNew
呼叫(间接,可能)_Py_NewReference
在引擎盖下。此函数用于将新创建的引用的引用计数设置为1。你知道吗随后的
Py_INCREF
将ref计数增加到2,从而确保Python永远不会释放这个对象,即使对它的所有引用都不存在,因为它的引用计数永远不会降到0。你知道吗Py_INCREF
调用是不必要的,因为这里没有与任何其他对象共享引用,您只是在本地使用它,然后将它传递给调用者。你知道吗相关问题 更多 >
编程相关推荐