对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了“内存泄露”





一、内存泄露的原因





对于 python 这种支持垃圾回收的语言来说,怎么还会有内存泄露? 概括来说,有以下三种原因:





1、 所用到的用 C 语言开发的底层模块中出现了内存泄露。





2、 代码中用到了全局的 list、 dict 或其它容器,不停的往这些容器中插入对象,而忘记了在使用完之后进行删除回收





3、 代码中有“引用循环”, python 垃圾处理机制无法进行回收





二、 内存泄露的诊断思路





无论是哪种方式的内存泄露,最终表现的形式都是某些 python 对象在不停的增长;因此,首先是要找到这些异常的对象。





 

三、 内存泄露的诊断步骤

 

用到的工具: gc 模块和 objgraph





objgraph 是一个用于诊断内存问题的有用的工具





1、 在服务程序的循环逻辑中,选择出一个诊断点



2、 在诊断点,插入如下诊断语句





import gc  

import objgraph  

### 强制进行垃圾回收  

gc.collect()  

### 打印出对象数目最多的 50 个类型信息  

objgraph.show_most_common_types(limit=50)  

 





3、 检查统计信息,找到异常对象。





运行加入诊断语句的服务程序,并将打印到屏幕上的统计信息重定向到日志中。





运行一段时间后,就可以来分析日志,看看哪些对象在不停的增长。





以我的有问题的程序为例,我将日志记录到 log.txt 中,运行一段时间后,发现 tuple 和 list 类型的对象不停增长:





# grep "^list " log.txt





# grep "^tuple " log.txt



 

由于 tuple 和 list 是一种通用的类型,因此,那些不停增长的 tuple 和 list 到底是什么对象,还是无法得知。我们还得想点办法追踪下去。





如果不停增长的对象,是一些非通用的类型(例如你自己实现的一个 class),那么问题就比较好定位了。





回到我的这个异常程序,为了找出 tuple 和 list 到底是什么? 我采用了排查的方式。由于程序的模块化还不错,我可以每次禁用一个模块,然后重新跑程序,看看在这种情况下, tuple 和 list 是否仍然不停增长。这样,很快就能将故障定位到具体的模块中。

python 内存泄露的诊断的更多相关文章

  1. python 内存泄露的诊断 - 独立思考 - ITeye技术网站

    python 内存泄露的诊断 - 独立思考 - ITeye技术网站 python 内存泄露的诊断 博客分类: 编程语言: Python Python多线程Blog.net  对于一个用 python ...

  2. python内存泄露的诊断(转)

    本篇文章非原创,转载自:http://rstevens.iteye.com/blog/828565 . 对于一个用 python 实现的,长期运行的后台服务进程来说,如果内存持续增长,那么很可能是有了 ...

  3. 记一次调试python内存泄露的问题

    转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...

  4. 排查python内存泄露中几个工具的使用

    本文主要介绍3个工具:pdb,objgraph,以及pympler. 1.pdb pdb是专门用于python代码调试,模仿gdb. 使用pdb可以查看堆栈,打印变量等. 这里介绍的是命令行下的pdb ...

  5. 关于排查python内存泄露的简单总结

    这次的内存泄露问题是发生在多线程场景下的. 各种工具都试过了,gc,objgraph, pdb,pympler等,仍然没有找到问题所在. pdb感觉用起来很方便,可以调试代码,对原来的代码无侵入性. ...

  6. python内存泄露memory leak排查记录

    问题描述 A服务,是一个检测MGR集群主节点是否发生变化的服务,使用python语言实现的. 针对每个集群,主线程会创建一个子线程,并由子线程去检测.子线程会频繁的创建和销毁. 上线以后,由于经常会有 ...

  7. 使用gc、objgraph干掉python内存泄露与循环引用!

    Python使用引用计数和垃圾回收来做内存管理,前面也写过一遍文章<Python内存优化>,介绍了在python中,如何profile内存使用情况,并做出相应的优化.本文介绍两个更致命的问 ...

  8. python内存泄露诊断过程记录pyrasite

    工具:pyrasite;包含三个命令行 pyrasite / pyrasite-shell / pyrasite-memory-viewer 安装:gdb meliae urwid 说明:Pyrasi ...

  9. python内存泄露查找

    1 前言: 1.1 像Java程序一样,虽然Python本身也有垃圾回收的功能,但是同样也会产生内存泄漏的问题 1.2 在Python程序里,内存泄漏是由于一个长期持有的对象不断的往一个dict或者l ...

随机推荐

  1. 使用 Spring Social 连接社交网络

    Spring Social 框架是spring 提供社交平台的分享组件 https://www.ibm.com/developerworks/cn/java/j-lo-spring-social/

  2. win10 打开chm文件内容空白如何解决

    win10 打开chm文件内容空白如何解决 .CHM文件是非常常见的帮助文件格式.由于其便携性,很多小说或杂志也会采用chm格式.win7/win8.1/win10系统,由于采用了UAC,致使原本在x ...

  3. postgresql用sql语句查询表结构

    用到的postgresql系统表 关于postgresql系统表,可以参考PostgreSQL 8.1 中文文档-系统表. pg_class 记录了数据库中的表,索引,序列,视图("关系&q ...

  4. js 零碎

    function具有一个属性是length,表示希望接收到的命名参数的个数.可以通过arguments获取参数.arguments.callee表示函数本身,递归时有用,也可以通过arguments. ...

  5. vue 与 angular 的区别

    vue仅仅是mvvm中的view层,只是一个如jquery般的工具库,而不是框架,而angular而是mvvm框架. vue的双向邦定是基于ES5 中的 getter/setter来实现的,而angu ...

  6. Python2 下Ubuntu linux Mac 安装 PyV8

    在pip install PyV8(注意区分大小写)时,出现了如下报错 command 'x86_64-linux-gnu-gcc' failed with exit status 1 解决方案: 百 ...

  7. Python基础-判断闰年

    输入一个年份,判断该年份是否是闰年并输出结果.求它是否是闰年?要求:能被4整除不能被100整除或者能被400整除. y=input('请输入年份:') if(y%4==0 and y%100 != 0 ...

  8. 【codeforces 796D】Police Stations

    [题目链接]:http://codeforces.com/contest/796/problem/D [题意] 在一棵树上,保证每个点在距离d之内都有一个警察局; 让你删掉最多的边,使得剩下的森林仍然 ...

  9. 【[Offer收割]编程练习赛13 D】骑士游历(矩阵模板,乘法,加法,乘方)

    [题目链接]:http://hihocoder.com/problemset/problem/1504 [题意] [题解] 可以把二维的坐标转成成一维的; 即(x,y)->(x-1)*8+y 然 ...

  10. 【codeforces 779E】Bitwise Formula

    [题目链接]:http://codeforces.com/contest/779/problem/E [题意] 给你n个长度为m的二进制数 (有一些是通过位运算操作两个数的形式给出); 然后有一个未知 ...