除了通过引用计数直接销毁对象之外,python还是拥有内在GC机制的,并且也有完整的一套流程。
如果只有通过引用计数销毁对象这种机制,那么随便构造一个循环引用就会造成内存泄漏,比如下面的代码:
1 | def _dump_gc(): |
打印出来的结果是:
1 | 13707 |
很显然,当退出_test_internal作用域时,gc对象的数量没有变化,这就说明在_test_internal里创建的a、b两个对象没有被立即释放掉。如果注释掉两个append行,就能看到打印结果第三行变成了13707,说明a、b在退出函数时就被销毁了。
所以首先,我们从循环引用入手,来研究一下python的gc机制(好巧不巧的是,python的gc也是专门为循环引用而设置的)。调用gc.collect触发gc之后,会跑到gc_collect_main触发完整的gc流程。gc_collect_main是python整个gc流程的主入口,我们来看其中的代码: