zoukankan      html  css  js  c++  java
  • Python高级编程技巧

    Python 垃圾回收机制
    计数引用我们反复提过好几次, Python 中一切皆对象。因此,你所看到的一切变量,本质上都是对象的一个指针。

    那么,怎么知道一个对象,是否永远都不能被调用了呢?

    就是当这个对象的引用计数(指针数)为 0 的时候,说明这个对象永不可达,自然它也就成为了垃圾,需要被回收。

    import os
    import psutil
    
    # 显示当前 python 程序占用的内存大小
    def show_memory_info(hint):
        pid = os.getpid()
        p = psutil.Process(pid)
        
        info = p.memory_full_info()
        memory = info.uss / 1024. / 1024
        print('{} memory used: {} MB'.format(hint, memory))
        
    
    def func():
        show_memory_info('initial')
        a = [i for i in range(10000000)]
        show_memory_info('after a created')
    
    func()
    show_memory_info('finished')
    

    循环引用
    如果有两个对象,它们互相引用,并且不再被别的对象所引用,那么它们应该被垃圾回收吗?

    def func():
        show_memory_info('initial')
        a = [i for i in range(10000000)]
        b = [i for i in range(10000000)]
        show_memory_info('after a, b created')
        a.append(b)
        b.append(a)
    
    func()
    show_memory_info('finished')
    

    调试内存泄漏
    虽然有了自动回收机制,但这也不是万能的,难免还是会有漏网之鱼。内存泄漏是我们不想见到的,而且还会严重影响性能。有没有什么好的调试手段呢?

    它就是 objgraph,一个非常好用的可视化引用关系的包。在这个包中,我主要推荐两个函数,第一个是 show_refs(),它可以生成清晰的引用关系图。

    import objgraph
    
    a = [1, 2, 3]
    b = [4, 5, 6]
    
    a.append(b)
    b.append(a)
    
    objgraph.show_refs([a])
    

    dot转图片:https://onlineconvertfree.com/zh/

    总结

    • 垃圾回收是 Python 自带的机制,用于自动释放不会再用到的内存空间;
    • 引用计数是其中最简单的实现,不过切记,这只是充分非必要条件,因为循环引用需要通过不可达判定,来确定是否可以回收;
    • Python 的自动回收算法包括标记清除和分代收集,主要针对的是循环引用的垃圾收集;
    • 调试内存泄漏方面, objgraph 是很好的可视化分析工具。
  • 相关阅读:
    markdown转微信公众号编辑器
    微信公众号发布和群发的区别
    Win10自带HyperV虚拟机上安装Linux系统
    Sql优化的15个小技巧
    Md2All 简介 (公众号markdown排版)
    svg动态图
    Markdown的常用语法
    Md2All,把图片轻松上传到云图床,自动生成Markdown
    Postman 使用教程 API 接口自动化测试初探
    玩转公众号markdown排版
  • 原文地址:https://www.cnblogs.com/sakura579/p/12435879.html
Copyright © 2011-2022 走看看