在我的应用程序中,生成100个numpy数组(每个1000个复杂元素)并填充数据。然后经过多次迭代,一遍又一遍地修改数组元素。在初始生成之后,系统监视器报告大约50 Mb的RAM使用情况。虽然我没有生成任何新阵列,但每次迭代的足迹仍然增长了大约40 Mb。
我学会了here,垃圾收集器不处理numpy数组。所以我假设我生成的一些临时数组没有正确收集。
Here不幸的是,guppy.hpy()。heap()无法帮助分析numpy。
如何确定问题的根源,理想情况下,在任意次数的迭代中保持消耗不变?
我怀疑在分配here所描述的数组元素时,我可能会生成副本,然后不会进行垃圾回收。
我可以手动处理临时numpy数组以协助垃圾回收吗?
[更新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)
[更新2]:对于那些好奇的人来说,这是移动网络模拟器的一部分。运行virtualenv,Python 2.7.3,Numpy 1.6.2,SciPy 0.11.0b1
[更新3]:通过评论并检查系统监视器,我可以将'interferencep = ...' - 行识别为罪魁祸首。它分配了大量未释放的内存。但为什么呢?
答案 0 :(得分:5)
我遇到了同样的问题。不幸的是我找不到解决方法。唯一对我有用的是将代码重构为小的独立函数。应该制作这些函数,以便我可以说服自己我没有引用数组来阻止垃圾收集器收集数组。你应该特别注意通过切片等生成的数组视图......
为了使代码更高效,更不容易出现内存泄漏,我经常发现使用许多numpy函数提供的out = keyword参数很有用。
答案 1 :(得分:2)
通过使用系统监视器和代码检查/注释,我发现了内存泄漏。这是通过将numpy数组与不同文件中的空列表进行比较而引起的。我将在不同的地方挖掘泄漏并投票删除这个问题,因为我觉得它太具体了,无法帮助其他人。
[更新1]:描述问题根源的新问题: Why does comparison of a numpy array with a list consume so much memory?