我正在编写一个代码,在某些时候我需要解决大型稀疏矩阵的几个广义特征值问题。因为这些操作基本相似(只考虑了所考虑的矩阵的名称),所以我做了一个函数:
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。
答案 0 :(得分:0)
如果分配了一个Python对象,它就会被放到程序的堆上。
如果它是一个非常大的对象,只要需要,内存将通过mmap()
分配,然后再次释放。我不确定这是否会立即发生......
对于较小的对象,进程的brk()
边界将被移位。在这种情况下,分配内存。如果之后添加了一些其他对象并释放了以前的对象,则它们的内存在堆上是空闲的,但不能返回到操作系统。只有在释放堆上最末端的对象之后,才能将部分空闲区域返回到操作系统。
你说的是800 MB,这显然是如此之大以至于应该使用mmap()
方法,但如果数据由数千个较小的对象组成,那么它们可能会落在brk()
堆上