python 内存泄漏分析工具_Python 内存泄漏排查与分析

python 内存异常的几种情况代码内出现循环引用

全局变量数据太多

进程加载大量数据,长久持有不释放

现象

线上生产环境一些 tornado 服务(主要提供rest服务)进程占用内存过大:百兆到1G ,测试环境的同样服务未出现异常。

观察分析

1.确定是否是个别进程的特有现象

在一套环境中部署不同的tornado的服务,排除了tornado和第三方库的可能性。

2.利用linux top 等命令观察异常服务进程内存的增长情况

人工观察有异常内存的服务进程(2~3个小时观测一次),发现其内存占有率并不完全统一,即在进程启用之后,有的进程内存占有过大,有的正常,但是在相当长一段时间之后(一天以后),所有进程内存占有几乎趋于一个稳定的比较大的值。由此可以推断出以下几种情况:

生产环境请求复杂,测试环境和生产环境表现不一致,有可能是对某些api的不合法的请求(非法参数未处理)导致内存占用过大

某些api(单次请求的数据量较大)的并发量太大,同一时间内存占有量过大

隐式的改变了全局变量的值,导致变量数据增大,比如全局的list或者dict数据不断被添加

其他未知情况

对代码进行静态分析和检查, 排除了全局变量和循环引用的问题。

侦测线上api调用前后对进程内存的影响

为了能够非常细致的观测到线上api调用前后的进程内存占用率,在api调用的入口记录了当前进程的内存占用,并对日志以进程的id来区分,由于tornado的单进程特性,也可以用端口号来区分,这样日志的划分更稳定,毕竟进程id是个变数。

1

2

3

4

5

6

7

8

9def log_memory(self):

import psutil

import os

logger_name = ('app_%s'%self.application.settings.get('port'))

m_logger = loggers.getLogger(logger_name, '/var/log/app_%s.log'%logger_name)

process = psutil.Process(os.getpid())

m_logger.info('%s %s MB'%(self.request.path, process.memory_info()[0]/(1024*1024)))

m_logger.info(self.request.arguments)

psutil 提供了获取进程资源占用如内存,cpu,磁盘,网络等的api。为了能查看api调用的上下文环境,日志中还记录了api的请求参数。

解决

通过的日志分析发现,一个api在某些参数的边界未做处理时,会导致一部分很大的数据被加载到内存中。至此,这个问题的根源终于被找到了。

不过一个疑问是:python的进程内存增大之后,是否会让python解释器认为,该进程使用的峰值内存就是如此而不愿意交换给os呢

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值