我想知道我的Python应用程序的内存使用情况,并且特别想知道哪些代码块/部分或对象占用了大部分内存.Google搜索显示商业广告是Python Memory Validator(仅限Windows).
我没有尝试任何人,所以我想知道哪一个是最好的考虑:
提供大部分细节.
我必须对代码进行最少或不做任何更改.
我有一个包含大量对象的程序,其中许多是Numpy数组.我的程序很糟糕地交换,我正在尝试减少内存使用量,因为它实际上无法在我的系统上使用当前的内存要求.
我正在寻找一个很好的分析器,它可以让我检查各种对象消耗的内存量(我正在设想与cProfile相对应的内存),以便我知道在哪里进行优化.
我听说过关于Heapy的不错的东西,但遗憾的是Heapy不支持Numpy数组,而且我的大多数程序都涉及Numpy数组.
在我的应用程序中,生成了100个numpy数组(每个1000个复杂元素)并填充了数据.然后经过多次迭代,一遍又一遍地修改数组元素.在初始生成之后,系统监视器报告大约50 Mb的RAM使用情况.虽然我没有生成任何新阵列,但每次迭代的足迹仍然增长了大约40 Mb.
我在这里学到,垃圾收集器不处理numpy数组.所以我假设我正在生成一些操作数据的临时数组没有正确收集.
不幸的是,这里说guppy.hpy().heap()无法帮助分析numpy.
如何识别问题的根源并理想地保持消耗在任何次数的迭代中保持不变?
我怀疑在分配这里描述的数组元素时可能会生成副本,然后不会进行垃圾回收.
我可以手动处理临时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)
Run Code Online (Sandbox Code Playgroud)
[更新2]:对于那些好奇的人来说,这是移动网络模拟器的一部分.运行virtualenv,Python 2.7.3,Numpy 1.6.2,SciPy 0.11.0b1
[更新3]:通过评论和检查系统监视器,我可以将'interferencep = ...' - 行识别为罪魁祸首.它分配了大量未释放的内存.但为什么?
为了测试 Pypy JIT 明显更快的说法,我编写了一个简单的代码,该代码重复添加两个大小为 1200x1200 的数组。我的代码如下
import numpy as np
import random
a=np.zeros((1200, 1200), dtype=np.float32)
b=np.zeros((1200, 1200), dtype=np.float32)
import timeit
#Start timer
start=timeit.default_timer()
#Initialize the arrays
for j in range(1200):
for k in range(1200):
a[j][k]=random.random()
b[j][k]=random.random()
#Repeatedly add the arrays
for j in range(10):
a=np.add(a,b)
#Stop timer and display the results
stop=timeit.default_timer()
print stop-start
Run Code Online (Sandbox Code Playgroud)
对于普通的 python,执行时间约为 1.2 - 1.5 秒。但是使用 Pypy 它会超过 15 秒吗?同样在上述情况下,我只添加了 10 次数组。如果我将此值增加到 1000,我的计算机将停止响应。我发现这是因为使用 pypy 时几乎消耗了整个 RAM。难道我做错了什么?或者问题是其他的?