ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
![](https://img.kancloud.cn/41/e0/41e066af9a6c25a24868d9667253ec98_1241x333.jpg) ***** ## Python 垃圾回收机制 计数引用我们反复提过好几次, Python 中一切皆对象。因此,你所看到的一切变量,本质上都是对象的一个指针。 <br>那么,怎么知道一个对象,是否永远都不能被调用了呢? <br>就是当这个对象的引用计数(指针数)为 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]) ~~~ ![](https://img.kancloud.cn/ea/41/ea41aeebb7e67840ffaddef7414af1ef_477x259.png) dot转图片:[https://onlineconvertfree.com/zh/](https://onlineconvertfree.com/zh/) ### 总结 * 垃圾回收是 Python 自带的机制,用于自动释放不会再用到的内存空间; * 引用计数是其中最简单的实现,不过切记,这只是充分非必要条件,因为循环引用需要通过不可达判定,来确定是否可以回收; * Python 的自动回收算法包括标记清除和分代收集,主要针对的是循环引用的垃圾收集; * 调试内存泄漏方面, objgraph 是很好的可视化分析工具。