谈谈如何手动释放Python的内存


Posted in Python onDecember 17, 2016

在上篇博客中,提到了对一个脚本进行的多次优化。当时以为已经优化得差不多了,但是当测试人员测试时,我才发现,踩到了Python的一个大坑。

在上文的优化中,对每500个用户,会进行一些计算并记录结果在磁盘文件中。原本以为这么做,这些结果就在磁盘文件中了,而不会再继续占用内存;但实际上,Python的大坑就是Python不会自动清理这些内存。这是由其本身实现决定的。具体原因网上多有文章介绍,这里就不copy了。

本篇博客将贴一个笔者的实验脚本,用以说明Python确实存在这么一个不释放内存的现象,另外也提出一个解决方案,即:先del,再显式调用gc.collect(). 脚本和具体效果见下。

实验环境一:Win 7, Python 2.7

from time import sleep, time 
import gc 
 
def mem(way=1): 
 print time() 
 for i in range(10000000): 
  if way == 1: 
   pass 
  else: # way 2, 3 
   del i 
    
 print time() 
 if way == 1 or way == 2: 
  pass 
 else: # way 3 
  gc.collect() 
 print time() 
   
if __name__ == "__main__": 
 print "Test way 1: just pass" 
 mem(way=1) 
 sleep(20) 
 print "Test way 2: just del" 
 mem(way=2) 
 sleep(20) 
 print "Test way 3: del, and then gc.collect()" 
 mem(way=3) 
 sleep(20)

运行结果如下:

Test way 1: just pass 
1426688589.47 
1426688590.25 
1426688590.25 
Test way 2: just del 
1426688610.25 
1426688611.05 
1426688611.05 
Test way 3: del, and then gc.collect() 
1426688631.05 
1426688631.85 
1426688631.95

对于way 1和way 2,结果是完全一样的,程序内存消耗峰值是326772KB,在sleep 20秒时,内存实时消耗是244820KB;

对于way 3,程序内存消耗峰值同上,但是sleep时内存实时消耗就只有6336KB了。

实验环境二: Ubuntu 14.10, Python 2.7.3

运行结果:

Test way 1: just pass 
1426689577.46 
1426689579.41 
1426689579.41 
Test way 2: just del 
1426689599.43 
1426689601.1 
1426689601.1 
Test way 3: del, and then gc.collect() 
1426689621.12 
1426689622.8 
1426689623.11
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py 
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem 
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 10.0 6.0 270916 245564 pts/1 S+ 14:39 0:03 python test_mem.py 
ubuntu 9134 0.0 0.0 8104 924 pts/2 S+ 14:40 0:00 grep --color=auto test_mem 
ubuntu@my_machine:~$ ps -aux | grep test_mem 
Warning: bad ps syntax, perhaps a bogus '-'? See http://procps.sf.net/faq.html 
ubuntu 9122 11.6 0.1 30956 5608 pts/1 S+ 14:39 0:05 python test_mem.py

结论:

以上说明,当调用del时,其实Python并不会真正release内存,而是将其继续放在其内存池中;只有在显式调用gc.collect()时,才会真正release内存。

进一步:

其实回到上一篇博客的脚本中,也让其引入gc.collect(),然后写个监控脚本监测内存消耗情况:

while ((1)); do ps -aux | sort -n -k5,6 | grep my_script; free; sleep 5; done

结果发现:内存并不会在每500个用户一组执行完后恢复,而是一直持续消耗到仅存约70MB时,gc才好像起作用。本环境中,机器使用的是Cloud instance,总内存2G,可用内存约为1G,本脚本内存常用消耗是900M - 1G。换句话说,对于这个脚本来说,gc并没有立即起作用,而是在系统可用内存从1 - 1.2G下降到只剩70M左右时,gc才开始发挥作用。这点确实比较奇怪,不知道和该脚本是在Thread中使用的gc.collect()是否有关,或者是gc发挥作用原本就不是可控的。笔者尚未做相关实验,可能在下篇博客中继续探讨。

但是,可以肯定的是,若不使用gc.collect(), 原脚本将会将系统内存耗尽而被杀死。这一点从syslog中可以明显看出。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现Linux下守护进程的编写方法
Aug 22 Python
python调用java模块SmartXLS和jpype修改excel文件的方法
Apr 28 Python
Python使用Scrapy爬取妹子图
May 28 Python
Python3字符串学习教程
Aug 20 Python
python 打印对象的所有属性值的方法
Sep 11 Python
python处理Excel xlrd的简单使用
Sep 12 Python
python实现Floyd算法
Jan 03 Python
关于python写入文件自动换行的问题
Jun 23 Python
python 美化输出信息的实例
Oct 15 Python
对python中GUI,Label和Button的实例详解
Jun 27 Python
解决paramiko执行命令超时的问题
Apr 16 Python
Python制作动态字符画的源码
Aug 04 Python
深入理解NumPy简明教程---数组3(组合)
Dec 17 #Python
深入理解NumPy简明教程---数组2
Dec 17 #Python
深入理解NumPy简明教程---数组1
Dec 17 #Python
Python脚本获取操作系统版本信息
Dec 17 #Python
详解python中xlrd包的安装与处理Excel表格
Dec 16 #Python
详解python开发环境搭建
Dec 16 #Python
python制作爬虫爬取京东商品评论教程
Dec 16 #Python
You might like
解析如何在PHP下载文件名中解决乱码的问题
2013/06/20 PHP
php银联网页支付实现方法
2015/03/04 PHP
PHP内存缓存功能memcached示例
2016/10/19 PHP
Firebug 字幕文件JSON地址获取代码
2009/10/28 Javascript
基于Jquery的仿照flash放大图片效果代码
2011/03/16 Javascript
jQuery实现图片信息的浮动显示实例代码
2013/08/28 Javascript
js Array操作的最简短最容易理解方法
2013/12/09 Javascript
jQuery的Scrollify插件实现滑动到页面下一节点
2015/07/05 Javascript
Bootstrap Modal遮罩弹出层(完整版)
2016/11/21 Javascript
微信小程序 scroll-view组件实现列表页实例代码
2016/12/14 Javascript
Webpack打包慢问题的完美解决方法
2017/03/16 Javascript
ejsExcel模板在Vue.js项目中的实际运用
2018/01/27 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
2018/08/25 Javascript
浅谈JavaScript_DOM学习篇_图片切换小案例
2019/03/19 Javascript
Node.js中console.log()输出彩色字体的方法示例
2019/12/01 Javascript
黑科技 Python脚本帮你找出微信上删除你好友的人
2016/01/07 Python
Django接受前端数据的几种方法总结
2016/11/04 Python
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
python实现八大排序算法(2)
2017/09/14 Python
Python 逐行分割大txt文件的方法
2017/10/10 Python
对python 各种删除文件失败的处理方式分享
2018/04/24 Python
Python Requests模拟登录实现图书馆座位自动预约
2018/04/27 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
python应用文件读取与登录注册功能
2019/09/23 Python
Python实现不规则图形填充的思路
2020/02/02 Python
解决Jupyter NoteBook输出的图表太小看不清问题
2020/04/16 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
2020/06/23 Python
美国亚洲时尚和美容产品的一站式网上商店:Stylevana
2019/09/05 全球购物
小学新学期教师寄语
2014/01/18 职场文书
最新创业融资计划书
2014/01/19 职场文书
中学生自我鉴定
2014/02/04 职场文书
网络技术专业求职信
2014/02/18 职场文书
临床医学专业求职信
2014/08/08 职场文书
大学生万能检讨书范例
2014/10/04 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
Python中OpenCV实现简单车牌字符切割
2021/06/11 Python