问题描述

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. python之初入Python

    python优缺点: Python的优点很多,简单的可以总结为以下几点. 简单和明确,做一件事只有一种方法. 学习曲线低,跟其他很多语言相比,Python更容易上手. 开放源代码,拥有强大的社区和生态 ...

  2. 离线下载pytorch安装包

    1. 选择合适的安装包下载 https://anaconda.org/pytorch/repo?type=conda&label=main 2. 安装命令: conda install 安装包 ...

  3. phpMyAdmin出现Fatal error: Maximum execution time of 300 seconds

    在mysql用phpMyAdmin导入大数据的时候出现:Fatal error: Maximum execution time of 300 seconds exceeded in D:/查了很多文章 ...

  4. Android异常与性能优化相关面试问题-OOM异常面试问题详解

    什么是OOM? 当前占用的内存加上我们申请的内存资源超过了Dalvik虚拟机的最大内存限制就会抛出Out Of Memory异常. 一些容易混淆的概念: 内存溢出:指的就是OOM. 内存抖动:是短时间 ...

  5. SCU 4584 tarjan+最大权闭合子图

    把每个点的点权当做是W[i]-V[i] 题目一眼是最大权闭合子图 但是可能会有重边自环和环 需要先搞成简单图 再tarjan缩点 缩点后就是裸的最大权闭合子图 #include<bits/std ...

  6. Tomcat基础知识

    介绍Tomcat之前先介绍下Java相关的知识. 各常见组件: 1.服务器(server):Tomcat的一个实例,通常一个JVM只能包含一个Tomcat实例:因此,一台物理服务器上可以在启动多个JV ...

  7. MariaDB安装与使用

    下载地址:https://downloads.mariadb.org/ 下载相对应的电脑版本程序 等待下载完成...... 安装教程: 双击运行 设置数据库的密码 等待安装完成.. 这样就完成安装了. ...

  8. SQL Server 删除日志文件

    -- 查询日志文件名,用于下面删除 USE [data_name] GO SELECT file_id, name FROM sys.database_files /*删除指定数据库的日志文件*/ U ...

  9. Vue:选中商品规格改变字体和边框颜色(默认选中第一种规格)

    效果图: CSS: <div class="label"> <p>标签类别</p> <ul> <li v-for=" ...

  10. VUE路由过度效果vs缓存

    app页面 router.js