python内存泄露memory leak排查记录
问题描述
A服务,是一个检测MGR集群主节点是否发生变化的服务,使用python语言实现的。
针对每个集群,主线程会创建一个子线程,并由子线程去检测。子线程会频繁的创建和销毁。
上线以后,由于经常会有功能发布,从而重启服务,开始一段时间没有发现问题。
半个月前的周二服务发布后,大约一周时间,没有再发布。到周末的时候,突然告警系统负载高,经过排查,发现内存几乎耗尽,并查到是A服务占用巨大内存,没有释放。
排查过程
已经确定,A服务是存在内存泄露的,到底是什么地方内存使用完,却没有释放呢?
这是一个令人头疼的问题,以前确实没有遇到过Python的内存泄露。
首先,网上搜索关于python内存泄漏的问题。大体了解到,Python的内存回收是基于引用计数的,也就是说,如果某个对象被使用一次,引用计数就会增加1。对象的引用计数为0时,内存就会被回收掉。
常见的导致内存泄露的情况有两种:
- (1)对象一直被全局变量使用,全局变量生命周期比较长,所以内存一直得不到释放。
- (2)循环引用中的对象定义了__del__的情况.
网上提供了各种用于排查内存泄露的工具,例如objgraph、guppy、pympler等,其具体使用参考文后的链接。
看了半天这些工具的使用,感觉还是应该看看自己代码,是不是存在对象使用完,但是一直被引用的情况。
首先,排查内存泄露的位置是在主线程还是子线程。通过查看,发现「子线程一直在执行」与「子线程频繁创建和退出」两种情况下,内存消耗差别较大, 而且「子线程一直在执行」内存消耗很小。这样,就可以定位到,内存泄露位置是在主线程或「子线程loop之前的代码」。
接着,屏蔽子线程,发现内存正常。
所以,定位到问题是在「子线程loop之前的代码」中。
最后,发现是频繁调用第三方包的函数导致的。
解决办法
找到问题的原因了,那么解决方法就好办了。改用其他的包或修改使用方式,绕开这个大坑。
参考
一次调试python内存泄露的问题
使用gc、objgraph干掉python内存泄露与循环引用!
Python内存优化:Profile,slots,compact dict
python内存泄露memory leak排查记录的更多相关文章
- SQL Server 内存泄露(memory leak)——游标导致的内存问题
原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...
- 内存溢出(Oom)和内存泄露(Memory leak)
1.概念 内存溢出(Oom):1.内存不够用:2.数据长度短的数据类型存储了一个数据长度较大的数据类型:3.一个结果 内存泄露(Memory leak):1.忘记释放已用内存,内存管理较为常见的现象: ...
- 利用linux的mtrace命令定位内存泄露(Memory Leak)
一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位. 以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...
- 内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别
内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数 ...
- 使用JProfiler分析定位java内存泄露memory leak
使用jprofiler远程profile JBoss应用服务器 项目中发现JBoss出现内存泄露, 从2G一直涨到3.5G左右 开始考虑使用jmap dump出内存来, 在用jhap打开浏览器分析. ...
- Java 基础 - 内存泄露Memory leak & 内存溢出Out of memory
内存泄露 & 内存溢出 关系 https://www.cnblogs.com/panxuejun/p/5883044.html 内存泄露的6种情况: https://blog.csdn.net ...
- 内存泄露 memory leak 的原因
#include <iostream> using namespace std; void foo() { MyClass *x; x = new MyClass(); //指向的丢失了 ...
- Android 内存管理 &Memory Leak & OOM 分析
转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...
- 内存泄漏(Memory Leak)
什么情况下会导致内存泄露(Memory Leak)? Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用 的内存空间是有限的.如果我们的 ...
随机推荐
- Vagrant box 增加磁盘容量方法
一直以来都是以vagrant+docker作为开发环境,可是久而久之,原Box自带的8G容量就捉襟见肘了.时不时需要手动删除一些东西. Virtualbox 本身只支持vdi硬盘文件格式的扩容,对vm ...
- vue+ckEditor5
1.安装依赖 "@ckeditor/ckeditor5-build-balloon": "^10.1.0", "@ckeditor/ckeditor5 ...
- textarea框自适应高度
export function autoTextarea(elem, extra, maxHeight){ /**textarea文本域随内容的多少而调整高度 */ extra = extra || ...
- Centos 7.0 界面
执行:systemctl get-default //显示默认的界面方式 multi-user.target //命令行界面 graphical.target //图形化界面 执行:systemctl ...
- SQL语句复习【专题九】
SQL语句复习[专题九] 视图:View视图的概念:视图是从若干基本表或其他视图构造出来的表.在创建一个视图时,只是存放的视图的定义,也即是动态检索数据的查询语句,而并不存放视图对应的数据在用户使用视 ...
- c++编程的字符集及其转换
一.两种字符集 多字节字符集(MBCS):因为计算机最早是在英语国家诞生的,大多数英文信息是由英文字母.数字以及一些其它字符构成了一个128个字符的ASCII字符集.本来这对于英语国家来说够用了.但是 ...
- python文件操作:文件指针移动、修改
一.文件指针移动 二.修改 一.文件指针移动 #大前提:文件内指针的移动是Bytes为单位的,唯独t模式下的read读取内容个数是以字符为单位 # f.read(3) # with open('a ...
- 对路径“xxxxx”的访问被拒绝。
对路径“D:\\Weixin\\WechatWeb\\wapMxApi\\JsonFile\\WaterPrice.json”的访问被拒绝. 本地vs2013编译调试是没有问题的但是发布后就不能倍访问 ...
- java线程基础巩固---构造Thread对象你也许不知道的几件事
关于Thread的构造在JDK文档中如下: 之后会把上面所有的构造都会学习到,这次主要是去研究一下图上标红的默认构造,当然大家肯定对于它都有些不屑,这有啥可学的,不new一个然后start线程不就启动 ...
- Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/dom4j/io/SAXReader
Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/dom4j/io/SAXReader ...