1.明确内存泄漏的几种场景。
1.没有开gc,或者gc设为debug状态,导致交叉引用没有被回收调
2.如果一个数据在逻辑上不应该存在,但是因为代码上没有做相关清除操作,导致他还存在,也是一种泄漏
举个栗子,例如我要记录最近50天的某个基金的日化收益率,定义一个全局的字典global_dict,运行了一个脚本进行计算,没10分钟算一次,但是我没有进行clear操作,每次的计算只是单纯的赋值dict[date] = rate,按理来说dict["五十天前"]的收益率都是不需要的,就是一种泄漏。
3.这种情况出现在python3.4之前,因为3.4已经修复了,是这样的,如果一个类定义了__del__,并且该类存在循环引用的情况,这时候gc就会把这个类放在gc.garbage当中,不会去做回收,可以说是跳出了分代回收的机制,但是3.4之后的版本就没有这种情况,会把他回收调。
2.根据场景去找问题
1.如果是第一种情况解决就最简单了,可以用某个调试库连接到线上的进程,这里推荐pyrasite,但是要注意,这东西很久都没有更新了,所以有可能会和py的版本出现不相容的情况,例如python3.6就把itervalues改为values,导致一些工具用不到,不过没关系,我们只是用它来连上去,看gc而且,等我们连上进程后,就可以调用gc.isenable()去看gc有没有打开了或者状态是否正确
2.第二种情况就比较复杂了,我建议线下压测复现,不管