2016-07-20 6 views
0

Я пишу модуль CPython mrloader поверх библиотеки C, я скомпилировал исходный код и начал делать некоторые тесты.Управление памятью CPython

Python занимает 4 Гб ОЗУ для запуска 100 циклов итерации для получения некоторых данных из сети. Это большая проблема, поэтому я использовал resource, чтобы ограничить объем оперативной памяти и проверить, освобождает ли память Python память. Я получил Segmentation fault.

Я использовал this документацию и this, чтобы написать модуль, и я думаю, что я делаю что-то неправильно, когда собираются объекты, потому что, если я не ограничу ОЗУ, он заканчивает цикл 100, но использует 4 ГБ памяти.

В коде 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); 
} 

Я правильно ли освобождаю память?

Я ценю ваше время, помогая мне.

+1

Ваш тип расширения содержит кучу указателей. Неясно, как они используются, но если кому-либо из них в любой момент назначить единственный указатель на блок памяти, который должен быть освобожден, тогда функция dealloc должна обрабатывать освобождение этой памяти, когда это необходимо. Более того, в этом случае методы вашего типа должны обрабатывать эти элементы соответствующим образом - например, освобождая заостренную память до перезаписывания значения указателя другим. –

+0

Спасибо @JohnBollinger, они освобождены разными способами, а closeAll(). Я ищу, какие ссылки не очищены. –

+0

CPython использует подсчет ссылок, что означает, что данные освобождаются как можно скорее, если только не существует циклов. Если вы никогда не создаете циклические структуры данных, то, что вы делаете с 'setrlimit', не может помочь. Если вы используете циклические структуры данных, более вероятно, помогут интерфейсы ['gc'] (https://docs.python.org/3/library/gc.html). – zwol

ответ

0

Я нашел решение, я использовал 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, я назвал free() перед разрушением PyObject себя. Теперь программа не использует более 100 Мб, массив большой.

Освобождает функция:

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