Уменьшение объема памяти numpy в долговременном приложении

в моем приложении генерируется и заполняется данными сто массивов numpy (по 1000 сложных элементов каждый). Затем на протяжении многих итераций элементы массива изменяются снова и снова. После первого поколения Системный монитор сообщает об использовании ОЗУ объемом около 50 Мб. Хотя я не генерирую никаких новых массивов, след продолжает расти примерно на 40 Мб за итерацию.

узнал здесь, что сборщик мусора не обрабатывает массивы numpy. Так Что Я ... предположим, что некоторые временные массивы, которые я генерирую для управления данными, собраны неправильно.

здесь там написано, что гуппи.hpy ().к сожалению, heap() не помогает при профилировании numpy.

Как я могу определить источник проблемы и в идеале сохранить константу потребления на любом количестве итераций?

Я подозреваю, что я могу генерировать копии при назначении элементов массива, как описано здесь, которые потом не сборка мусора.

могу ли я вручную удалить временные массивы numpy для помощи в сборе мусора?

[Update 1]: Пример кода

этот кусок кода вызывается тысячи раз. Каждый раз след увеличивается. Я не понимаю, почему, потому что, насколько я понимаю, это только чтение существующих массивов и манипулирование другими существующими массивами. Какие-нибудь из этих операций срезания делают что-то непреднамеренное? (Извините за длину строки. Я могу упростить это, но тогда я возможно, я тоже скрываю свои ошибки.)

for ts in np.arange(numTimeslots):
            for fc in np.arange(numFreqChunks):
                interfencep = np.sum( np.dot(np.dot(self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts] ,np.diag(cell.OFDMA_power[:,fc,ts])),self.baseStations[bs].cells[cell].CSI_OFDMA[:,:,fc,ts].conj().T) for bs in self.baseStations for cell in bs.cells if cell != self._cell) 
                noisep = np.eye(self.antennas) * (self.noisePower / numFreqChunks)
                self.OFDMA_interferenceCovar[:,:,fc,ts] = noisep + interfencep
                self.OFDMA_EC[:,:,fc,ts] = (np.dot(np.dot(self.OFDMA_CSI[:,:,fc,ts],linalg.inv(noisep+interfencep)),self.OFDMA_CSI[:,:,fc,ts].conj().T))
                eigs = linalg.eig(self.OFDMA_EC[:,:,fc,ts])[0]
                self.OFDMA_SINR[:,fc,ts] = np.real(eigs)

[Update 2]: для любопытных это часть симулятора мобильной сети. Работает на virtualenv, Python 2.7.3, Numpy 1.6.2, SciPy 0.11.0b1

[Update 3]: комментируя его и проверяя Системный монитор, я могу определить 'interferencep = ...- ...линия виновника. Он выделил значительную память, которая не освобождается. Но почему?

2 ответов


У меня была такая же проблема. К сожалению, я не нашел обходного пути. Единственное, что сработало для меня, - это рефакторинг кода в небольшую изолированную функцию. Эти функции должны быть сделаны так, чтобы я мог убедить себя, что я не держу ссылок на массивы, которые удерживают сборщик мусора от сбора массивов. Вы должны уделять особое внимание представлениям массива, которые генерируются срезом и т. д...

чтобы сделать код более эффективным и менее подверженным утечкам памяти, я часто найдено полезным использовать аргумент out= keyword, предоставляемый многими функциями numpy.


с помощью системного монитора и проверки кода / комментирования я обнаружил утечку памяти. Это было вызвано сравнением массива numpy с пустым списком в другом файле. Я покопаюсь в утечке в другом месте и проголосую за удаление этого вопроса, поскольку я нахожу его слишком конкретным, чтобы помочь кому-либо еще.

[Update 1]: новый вопрос, описывающий источник проблемы: почему сравнение массива numpy со списком потребляет так много памяти?