python之记录一次内存泄露

本文介绍了一个Python应用在长时间运行后出现严重内存泄露的问题,并详细分析了导致内存泄露的原因及解决方案。通过使用Pympler工具定位到问题代码为未正确清理线程引用,最终通过调整代码逻辑解决了内存泄露。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题现象

手头一个系统上线后,节点机中agent应用在运行10天后,占用系统内存居然高达10GB以上,这显然是发生了严重内存泄露。

 

问题原因

python是动态语言,对用动态语言的内存分析不是很容易,尝试了一下比较经典的内存分析工具meliae,但是发现不是很好用。查了很多资料后,发现了https://github.com/pympler/pympler 这个工具,官方文档地址为:

http://pythonhosted.org/Pympler/tutorials/muppy_tutorial.html

具体的分析过程我就不在这里描述了,大家可以通过pympler的官方文档去尝试。

 

在跟踪分析后,发现agent代码中的ProgressThread在一直增长,没有被释放。相关代码如下:

        progress_thread = ProgressThread(vid, segments, master_urls, self.hostname)
        progress_thread.setDaemon(True)
        progress_thread.start()
        self.progress_threads.append(progress_thread)

 可以看到,在类对象中,progress_threads这个列表,每次创建一个ProgressThread线程对象时,就会把对象插入到progress_threads列表中。

 

python的垃圾回收机制中,会自动对引用计数为0的对象回收。这里每次创建的线程对象,都被插入到progress_threads中,这导致了即使线程运行完毕了,其引用计数一直为1,导致所有的线程对象无法被回收。

 

问题解决

知道了问题原因,就很好解决了。在线程退出的地方,加入如下一行代码

            if progress_thread.if_stop == True:
                self.progress_threads.remove(progress_thread)

 让线程对象的引用计数为0,就解决了这个问题。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值