Python:使用函数最小化内存使用

时间:2015-01-16 14:49:50

标签: python function memory-management eigenvalue

我正在编写一个代码,在某些时候我需要解决大型稀疏矩阵的几个广义特征值问题。因为这些操作基本相似(只考虑了所考虑的矩阵的名称),所以我做了一个函数:

def eig_prob(myvariables):
  # this is just a simplified example
  name = 'iteration_'+myvariables["i"]
  A = myvariables["A"]
  B = myvariables["B"]
  N = myvariables["nb_eig"]
  Z,V = eigsh(A,N,B,sigma = 1)
  # save in Matlab format
  scipy.io.savemat(files["exec"]+name+".mat",{"Z":Z,"V":V})

由于我没有向主函数返回任何参数,我希望在调用eig_prob之前和之后RAM内存的数量是相同的。

事实上,我观察到在调用eig_prob期间RAM内存的消耗增加了大约800 Mb,这是预期的,并且这个内存在调用后没有释放,这对我来说似乎很惊讶。

这种行为有什么解释吗?可以避免吗?我是否需要将我的函数作为子进程运行以避免过度消耗内存?

编辑:我的一位同事表示gs.collect() [1]可能有所帮助,确实如此!在函数后调用时,gs.collect()释放800 Mb。

[1] https://docs.python.org/2/library/gc.html

1 个答案:

答案 0 :(得分:0)

如果分配了一个Python对象,它就会被放到程序的堆上。

如果它是一个非常大的对象,只要需要,内存将通过mmap()分配,然后再次释放。我不确定这是否会立即发生......

对于较小的对象,进程的brk()边界将被移位。在这种情况下,分配内存。如果之后添加了一些其他对象并释放了以前的对象,则它们的内存在堆上是空闲的,但不能返回到操作系统。只有在释放堆上最末端的对象之后,才能将部分空闲区域返回到操作系统。

你说的是800 MB,这显然是如此之大以至于应该使用mmap()方法,但如果数据由数千个较小的对象组成,那么它们可能会落在brk()堆上