CPython内存管理

CPython memory management

我正在 C 库之上编写一个 CPython 模块 mrloader,我编译了源代码并开始进行一些测试。

Python 需要 4 Gb 的 RAM 到 运行 100 次迭代循环以从网络获取一些数据。这是一个大问题,所以我使用 resource 来限制 RAM 的数量并测试 Python GC 是否释放了内存。我得到了 Segmentation fault.

我使用 this documentation and this 编写模块,我认为我在收集对象时做错了什么,因为如果我不限制 RAM,它会完成 100 个循环,但它使用 4Gb内存。

在 mrloader CPython 代码中我有一个这样的结构:

typedef struct {
    PyObject_HEAD
    AL_KEY ienaKey;
    char* dataPath;
    int nbParams;
    char** pListOfParams;
    CLIST_S* listParam;
    AL_DEFP_S *pListeParamInfo;
    int* pIndexParamIsTopana;
} MRLoader;

Python测试是这样的:

def limit_memory(maxsize):
    soft, hard = resource.getrlimit(resource.RLIMIT_AS)
    resource.setrlimit(resource.RLIMIT_AS, (maxsize, hard))

limit_memory(8589934592/10)

for i in xrange(100):
    print '----------------------------', i, '--------------------------' 
    obj = MRLoader.MRLoader(MR)
    obj.initReaderCadence(paramList, cadence, zdtStart, zdtStop)
    print obj.getData()
    obj.closeAll()

在 CPython 代码中,destructor 声明如下:

static void MRLoader_dealloc(MRLoader *self){
    self->ob_type->tp_free((PyObject *)self);
}

我是否正确地释放了内存?

感谢您花时间帮助我。

我找到了解决方案,我使用的是 PyArrayObject,我没有在声明的结构中保留指针。由于这个巨大的 numpy 数组,内存没有被释放。

所以我的结构现在看起来像这样:

typedef struct {
    PyObject_HEAD
    AL_KEY ienaKey;
    char* dataPath;
    int nbParams;
    char** pListOfParams;
    CLIST_S* listParam;
    AL_DEFP_S *pListeParamInfo;
    int* pIndexParamIsTopana;
    // Added this pointer to the numpy array
    reel64* pValueArray;
} libzihc_MRLoader;

并且在 deallocate 函数中,我在销毁 PyObject 自身之前调用了 free()。现在程序用不到100Mb,数组很大

取消分配函数:

static void MRLoader_dealloc(MRLoader *self){
    free(self->pValueArray)
    self->ob_type->tp_free((PyObject *)self);
}