我正在试图追踪pythoncc扩展中的内存泄漏,但是我很难理解为什么我的代码会给出引用计数。在
参考下面的代码示例,我想了解以下内容:
下面是一个简短的代码示例。 (我在Windows10上使用64位Python2.7,使用VS2012。)
// test.c : Test python reference counting
//
#include <stdlib.h>
#include <Python.h>
int main()
{
PyObject *PythonFunctionInput;
FILE *fid;
PyObject *tempPyObj;
PyObject *tempPyObjInt;
const int x = 1; // This is to mimic data in my actual application
const int y = 1;
const int z = 1;
Py_InitializeEx(0);
PythonFunctionInput = PyDict_New();
fid = fopen("TestOutputFile.txt", "wt");
fprintf(fid,"%d\n",(int)Py_REFCNT(PythonFunctionInput)); // 1
// Block 1
tempPyObj = PyString_FromString("name1");
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 1
PyDict_SetItemString(PythonFunctionInput,"fieldname1",tempPyObj);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 2
Py_DECREF(tempPyObj);
fprintf(fid,"%d\n",(int)Py_REFCNT(tempPyObj)); // 1
// Block 2
tempPyObjInt = PyInt_FromLong((long)x);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObjInt)); // 118 why?
PyDict_SetItemString(PythonFunctionInput,"fieldname2",tempPyObjInt);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObjInt)); // 119
Py_DECREF(tempPyObjInt);
fprintf(fid,"%d\n",(int)Py_REFCNT(tempPyObjInt)); //118
// Block 3
tempPyObjInt = PyInt_FromLong((long)y);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObjInt)); // 119
PyDict_SetItemString(PythonFunctionInput,"fieldname3",tempPyObjInt);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObjInt)); // 120
Py_DECREF(tempPyObjInt);
fprintf(fid,"%d\n",(int)Py_REFCNT(tempPyObjInt)); // 119
// Block 4
tempPyObj = PyInt_FromLong((long)z);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 120 why?
PyDict_SetItemString(PythonFunctionInput,"fieldname4",tempPyObj);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 121
Py_DECREF(tempPyObj);
fprintf(fid,"%d\n",(int)Py_REFCNT(tempPyObj)); // 120
// Block 5
tempPyObj = PyString_FromString("name5");
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 1 why?
PyDict_SetItemString(PythonFunctionInput,"fieldname5",tempPyObj);
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // 2
Py_DECREF(tempPyObj);
fprintf(fid,"%d\n",(int)Py_REFCNT(tempPyObj)); // 1
// Block 6
Py_DECREF(PythonFunctionInput);
fprintf(fid,"%d\n",(int)Py_REFCNT(PythonFunctionInput)); // 0
fprintf(fid,"%d ",(int)Py_REFCNT(tempPyObj)); // why not 0 ?
Py_Finalize();
fclose(fid);
return 0;
}
上面的代码生成一个如下所示的文件:
^{pr2}$我在代码中的每一行fprintf
的末尾添加了注释,以显示它显示的数字。在
您正在打印由
PyInt_FromLong()
创建的对象的引用计数。您很惊讶它是118(或其他值),而不是1。在这是因为Python中的小数字可以是“共享”的,这意味着运行时不需要每次创建一个小数字时都实际实例化一个新对象。这是为了提高效率:大多数Python程序都会创建一组数字,比如0、1、2、3等等,共享它们可以减少内存消耗和垃圾收集时间。在
相关问题 更多 >
编程相关推荐