首页 > 编程 > Python > 正文

对python程序内存泄漏调试的记录

2020-02-15 21:47:55
字体:
来源:转载
供稿:网友

问题描述

调试python程序时,用下面这段代码,可以获得进程占用系统内存值。程序跑一段时间后,就能画出进程对内存的占用情况。

def memory_usage_psutil(): # return the memory usage in MB import psutil,os process = psutil.Process(os.getpid()) mem = process.memory_info()[0] / float(2 ** 20) return mem

发现进程的内存占用一直再上涨,而这从逻辑上来说是不正常的,所以想到程序可能发生了Memory Leak。

python程序的Mem Leak

python程序不可能像C/C++一样出现malloc了的内存没有free这样的Memory Leak。但也会遇到“逻辑上没free”的情况,如下代码所示。

def foo(a=[]): a.append(time.time()) return a

参数a这样可迭代的对象,稍不注意,它就能增长的很快。说白了,python的Memory Leak,就是“进程占用的内存莫名其妙一直再升高”。进程占用内存一直升高,与逻辑预期不一致,就可能发生了Memory Leak。

以下面程序为例说明Memory Leak调试的过程:

def memory_usage_psutil(): # return the memory usage in MB import psutil,os process = psutil.Process(os.getpid()) mem = process.memory_info()[0] / float(2 ** 20) return memdef get_current_obj(a=[]): a.append([0]*1000) return adef main():  obj = [] for i in range(10000): obj = get_current_obj(obj) if(i%100==0):  print(memory_usage_psutil())if __name__=='__main__': main()

调试过程

用pmap -x [pid]查看进程占用的堆内存大小

首先想到,会不会是上面用的memory_usage_psutil函数统计错误呢。

先运行程序,再用pmap查看,发现进程内存占用确实很高。多次执行该命令,也可以发现内存一直升高。

强制执行GC(gc.collect())

在需要执行GC的地方加上gc.collect()

def main():  obj = [] for i in range(10000): obj = get_current_obj(obj) import gc;gc.collect() if(i%100==0):  print(memory_usage_psutil())

可以看到,强制GC后,程序执行变慢,但内存依然不断升高。

使用memory_profiler查看

安装memory_profiler

pip install -U memory_profiler

用@profile修饰需要查看内存的函数

@profiledef main():  obj = [] for i in range(10000): obj = get_current_obj(obj) if(i%100==0):  print(memory_usage_psutil())

用如下命令运行程序

python -m memory_profiler main.py

可以看到程序执行完成后,输出结果如下

Line # Mem usage Increment Line Contents================================================ 12 28.570 MiB 0.000 MiB @profile 13    def main(): 14 28.570 MiB 0.000 MiB obj = [] 15 106.203 MiB 77.633 MiB for i in range(10000): 16 106.203 MiB 0.000 MiB  obj = get_current_obj(obj) 17 106.203 MiB 0.000 MiB  if(i%100==0): 18 105.445 MiB -0.758 MiB  print(memory_usage_psutil())            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表