python内存监控工具memory_profiler和guppy的用法详解
python2.7在内存管理上相比python3还是有些坑的,其释放后的内存仍然保留在python的内存池中,不被系统所用。python循环引用的变量不会被回收,这会导致程序越运行,占用的内存越大。我在跑py-faster-rcnn的demo时,基本上跑2000张图像,16g内存就要爆了。于是尝试用python的内存监控工具来调试程序,找到不能膨胀的变量,然后del之,再手动回收内存gc.collec()
下面是我用的两个内存监视工具,一个是按每行代码查看内存占用的工具memory_profiler,一个是查看占用内存前十位变量的工具guppy。
1.memory_profiler
首先是安装:
pipinstall-Umemory_profiler
然后用profile修饰想要查看的函数名:如:
@profile defmy_func(): a=[1]*(10**6) b=[2]*(2*10**7) delb returna if__name__=='__main__': my_func()
输出结果:
Line# Memusage Increment LineContents
==============================================
3 @profile
4 5.97MB 0.00MB defmy_func():
5 13.61MB 7.64MB a=[1]*(10**6)
6 166.20MB 152.59MB b=[2]*(2*10**7)
7 13.61MB-152.59MB delb
8 13.61MB 0.00MB returna
memory_profiler功能强大,更多功能可以看官网这里
2.guppy
首先安装:
pipinstallguppy
然后import下
fromguppyimporthpy hxx=hpy() heap=hxx.heap() byrcs=hxx.heap().byrcs;
在主程序下增加:
print(heap)
输出示例:
IndexCount%Size%Cumulative%Kind(class/dictofclass) 0101242281944416958194441695list 11605634132546428326988096str 291472074561618401549697tuple 3102036648008438197698dictofmodule 4287131344808469542498dictoftype 52426531052808500595298types.CodeType 62364528368008528963299function 7287125696008554659299type 8169019208808573868099dict(noowner) 9123014272808588140899dictofclass
可以看到第一个list占了95%的内存,若print(heap)在主程序的循环中,可以查看每次循环后的变量内存占用情况。
输入以下命令,查看这个占内存最大的list中的数据类型:
byrcs[0].byid
最后测试后发现,test.py下get_im_blob等函数占用内存不断增大,每检测一副图像,该函数增加6-10MB内存开销。但奇怪的是用guppy查看前十个变量,并没有发现哪个变量有明显的内存增大迹象。于是猜测可能是每张图像推理后,推理的结果bbox,label,img等数据保存在了内存中,这样方便所有图像推理结束后,plt.show().于是修改程序,每张图像推理后,plt.show()一下。用memory_profiler发现内存不再继续增大,interesting!其实把plt.show()改成plt.close()也可以防止内存不断增大。具体原因肯定是python的内存回收机制规则导致的。
总结
以上所述是小编给大家介绍的python内存监控工具memory_profiler和guppy的用法详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!