问题描述

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排查记录的更多相关文章

  1. SQL Server 内存泄露(memory leak)——游标导致的内存问题

    原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...

  2. 内存溢出(Oom)和内存泄露(Memory leak)

    1.概念 内存溢出(Oom):1.内存不够用:2.数据长度短的数据类型存储了一个数据长度较大的数据类型:3.一个结果 内存泄露(Memory leak):1.忘记释放已用内存,内存管理较为常见的现象: ...

  3. 利用linux的mtrace命令定位内存泄露(Memory Leak)

    一谈到内存泄露, 多数程序猿都闻之色变. 没错, 内存泄露非常easy引入. 但非常难定位.  以你我的手机为例(如果不常常关机). 如果每天泄露一些内存, 那么開始的一个星期, 你会发现手机好好的. ...

  4. 内存溢出(Memory Overflow)和内存泄露(Memory Leak)的区别

    内存泄漏指你用malloc或new申请了一块内存,但是没有通过free或delete将内存释放,导致这块内存一直处于占用状态 内存溢出指你申请了10个字节的空间,但是你在这个空间写入11或以上字节的数 ...

  5. 使用JProfiler分析定位java内存泄露memory leak

    使用jprofiler远程profile JBoss应用服务器 项目中发现JBoss出现内存泄露, 从2G一直涨到3.5G左右 开始考虑使用jmap dump出内存来, 在用jhap打开浏览器分析. ...

  6. Java 基础 - 内存泄露Memory leak & 内存溢出Out of memory

    内存泄露 & 内存溢出 关系 https://www.cnblogs.com/panxuejun/p/5883044.html 内存泄露的6种情况: https://blog.csdn.net ...

  7. 内存泄露 memory leak 的原因

    #include <iostream> using namespace std; void foo() { MyClass *x; x = new MyClass(); //指向的丢失了 ...

  8. Android 内存管理 &Memory Leak & OOM 分析

    转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...

  9. 内存泄漏(Memory Leak)

    什么情况下会导致内存泄露(Memory Leak)? Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用 的内存空间是有限的.如果我们的 ...

随机推荐

  1. Spring AOP的理解和使用

    AOP是Spring框架面向切面的编程思想,AOP采用一种称为“横切”的技术,将涉及多业务流程的通用功能抽取并单独封装,形成独立的切面,在合适的时机将这些切面横向切入到业务流程指定的位置中. 掌握AO ...

  2. mmu(虚拟地址和物理地址简单图解)

  3. Tourist's Notes CodeForces - 538C (贪心)

    A tourist hiked along the mountain range. The hike lasted for n days, during each day the tourist no ...

  4. 从零开始学会GAN 0:第一部分 介绍生成式深度学习(连载中)

    本书的前四章旨在介绍开始构建生成式深度学习模型所需的核心技术.在第1章中,我们将首先对生成式建模领域进行广泛的研究,并从概率的角度考虑我们试图解决的问题类型.然后,我们将探讨我们的基本概率生成模型的第 ...

  5. java8学习之Lambda表达式初步与函数式接口

    对于Java8其实相比之前的的版本增加的内容是相当多的,其中有相当一大块的内容是关于Lambda表达式与Stream API,而这两部分是紧密结合而不能将其拆开来对待的,但是是可以单独使用的,所以从学 ...

  6. Python:pip 安装第三方库,速度很慢的解决办法

    场景 想安装 Django 库 在 cmd 敲入命令 pip install Django 但是发现下载安装文件非常慢 原因:实质访问的下载网站是 https://pypi.Python.org/si ...

  7. React组件:Dragact 0.1.4发布

    Dragact 是一款React组件,他能够使你简单.快速的构建出一款强大的 拖拽式网格(grid)布局. 仓库地址:Dragact 经过几天的迭代时间Dragact已经能够支持自由缩放功能了(res ...

  8. k8s安装flannel报错“node "master" pod cidr not assigned”

    一.在安装flannel网络插件后,发现pod: kube-flannel-ds 一直是CrashLoopBackOff 此报错是因为安装Kubeadm Init的时候,没有增加 --pod-netw ...

  9. (转载) Consul 使用手册(感觉比较全了)

    使用consul 介绍 Consul包含多个组件,但是作为一个整体,为你的基础设施提供服务发现和服务配置的工具.他提供以下关键特性: 服务发现 Consul的客户端可用提供一个服务,比如 api 或者 ...

  10. jsp上传超大文件解决方案

    1,项目调研 因为需要研究下断点上传的问题.找了很久终于找到一个比较好的项目. 在GoogleCode上面,代码弄下来超级不方便,还是配置hosts才好,把代码重新上传到了github上面. http ...