• 技术文章 >后端开发 >Python教程

    手动释放Python的内存的方法

    高洛峰高洛峰2017-03-24 17:37:10原创3520
    在上文的优化中,对每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的内存的方法的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:Python
    上一篇:详解Python的垃圾回收机制方法 下一篇:详解python用模块zlib压缩与解压字符串和文件的方法代码
    Web大前端开发直播班

    相关文章推荐

    • 一起聊聊Python的编码样式• 带你搞懂Python反序列化• 一起来分析Python怎么操作XML文件• 归纳整理!Python实用技巧总结• 归纳整理python正则表达式解析
    1/1

    PHP中文网