一、表现
运行环境:
# uname –a
Linux ** 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
# python2 –version
# cat /etc/*-release
CentOS Linux release 7.2.1511 (Core)
python进程在大量请求的处理过程中,内存持续升高。负载压力下降之后,内存并未下降。
python进程在大量请求的处理过程中,内存持续升高。负载压力下降之后,内存并未下降。
# ps aux | grep python2
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 124910 10.2 0.8 5232084 290952 ? Sl Mar17 220:37 python2 offline.py restart
# ~~~~~~
# 290M 内存占用
二、解决方法
三个步骤确定问题所在:
确认当时程序是否有异常行为;
排除行为异常后,查看python内存使用情况,确认所有相关对象的回收情况;
排除垃圾回收等python内部内存泄漏问题后,则可以定位到libc的malloc实现问题;
确定后可直接替换malloc模块为tcmalloc:、
LD_PRELOAD=”/usr/lib64/libtcmalloc.so” python x.py
三、问题定位过程解读
gdb-python:搞清楚python程序在做什么
首先确定python在做什么,是否有大内存消耗任务正在运行,或出现死锁等异常行为。
从gdb-7开始,gdb支持用python实现gdb扩展,可以像调试c程序一样,用gdb对python程序检查线程、调用栈等;且可同时打印python代码和内部c代码的调用栈。
这对于定位是python代码问题还是其底层c代码问题,有很大帮助。
准备gdb
首先安装python的debuginfo:
# debuginfo-install python-2.7.5-39.el7_2.x86_64
如果缺少debuginfo,当运行后续步骤时,gdb会提示,按提示安装完成即可:
Missing separate debuginfos, use: debuginfo-install python-2.7.5-39.el7_2.x86_64
接入gdb
可直接用gdb attach到1个python进程,查看其运行状态:
# gdb python 11122
attach之后进入gdb,基本检查步骤如下:
查看线程
(gdb) info threads
Id Target Id Frame
206 Thread 0x7febdbfe3700 (LWP 124916) “python2” 0x00007febe9b75413in select()