主页 > 原创 | 学习笔记 > opensips内存泄露初探

opensips内存泄露初探

opensips有私有内存和共享内存的区分,通过pkg_malloc分配私有内存,通过shm_malloc分配共享内存。

opensips可能存在内存泄露的表现为log中出现”out of memory”或者”no more memory”的信息,这时应先考虑是不是内存池给的太小了。在config.h文件中默认私有内存PKG_MEM_SIZE分配了2MB, 共享内存SHM_MEM_SIZE分配了32MB。可以适当增加内存池的大小,再确定还会不会出现内存不够的日志。
如果还存在问题,就应该开启mem log打log分析内存问题了。
如果通过top命令查看opensips内存占用一直居高不下,那一般就是有内存泄露了。

1.开启内存log
运行make menuconfig命令,进入Configure Compile Options-Configure Compile Flags, 用空格取消F_MALLOC的选定,选中DBG_QM_MALLOC,保存设置,然后重新编译opensips。

2.修改opensips.cfg配置文件
增加memlog=1,这个值应该小于”debug”值,之后运行opensipsctl restart重启opensips。

3.日志分析
官网给出了程序关闭和程序运行状态结束单一进程的方法,后者我没有成功。
通过opensipsctl stop停止opensips后,会在日志中打印内存相关的日志,如下片段为分配的过程

Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), called from xcap_ctl_functions.c: parserXcapGroup(562)
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), returns address 0x7f89b869d728 frag. 0x7f89b869d6f8 (size=24) on 1 -th hit
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), called from xcap_ctl_functions.c: parserXcapGroup(573)
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), returns address 0x7f89b869d908 frag. 0x7f89b869d8d8 (size=24) on 1 -th hit
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), called from xcap_ctl_functions.c: parserXcapGroup(585)
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: params (0x7f89b8636010, 24), returns address 0x7f89b869d818 frag. 0x7f89b869d7e8 (size=24) on 1 -th hit

其中 returns address 0x7f89b869d728 frag. 0x7f89b869d6f8 为返回地址,frag.为最后释放的标志。

下面片段为释放的过程

Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: freeing frag. 0x7f89b869c8e8 alloc'ed from xcap_ctl_functions.c: write_function(1652)
Sep 10 18:20:52 ty-desktop /sbin/opensips[24469]: freeing frag. 0x7f89b869c820 alloc'
ed from xcap_control.c: xcap_http_get(706)

4.处理脚本
我写了一个简单处理的脚本抛砖引玉,会生成没有释放的地址,但是这些地址不一定确实是内存泄露的地方。仅供分析,如果有好的建议请留言。
paste链接 https://notes.xdty.org/phcpkda9d

另外把/tmp目录映射到内存以提高性能,需要修改/etc/fstab增加如下片段,并执行命令mount -a

#修改run/shm的最大容量
tmpfs /run/shm tmpfs defaults,size=2048M 0 0
#把/tmp目录挂载到内存
tmpfs /tmp tmpfs defaults,size=2048M,noatime 0 0

脚本内容,同paste链接

#!/bin/bash
#title           :memleak.sh
#description     :This script will detect memory leak from opensips.
#author     :xdtianyu@gmail.com
#date            :20140910
#version         :0.1 beta
#usage     :bash memleak.sh
#notes           :enable opensips mem log flag
#bash_version    :4.3.11(1)-release
#==============================================================================

PID=$1
if [ -z "$PID" ];
then
    echo "param PID is NULL"
    exit 1;
fi
cat /var/log/opensips.log |grep "$PID" > $PID.log
cat $PID.log|egrep  "params \(0x|freeing frag." > $PID-mem.log
#cat $PID-mem.log | while read LINE
#do
#    echo $LINE
#done

egrep -o 'returns address 0x[0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z] frag. 0x[0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z]' $PID-mem.log > $PID-returns.log

cat $PID-returns.log | cut -c38-51 >$PID-returns-address.log

egrep -o 'freeing frag. 0x[0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z][0-9|a-z]' $PID-mem.log > $PID-free.log
cat $PID-free.log | cut -c15-28 >$PID-freed-address.log

cp $PID-returns-address.log /tmp/$PID-leak-address.log

i=1;
PARAM="";
cat $PID-freed-address.log | while read LINE
do
    ((i++));
    NUM=`cat /tmp/$PID-leak-address.log|grep $LINE -n -m 1|head -1|egrep -o '^[0-9]+'`
    if [ -n "$NUM" ];
    then
        #PARAM="$PARAM,$NUM"
        PARAM="$NUM""d"
        echo $i: 'find line '$NUM
        sed -i $PARAM /tmp/$PID-leak-address.log
    fi
done
#((i++));

#PARAM="$i$PARAM""d"
#echo $PARAM >param.txt
#sed -i $PARAM $PID-leak-address.log

cp /tmp/$PID-leak-address.log $PID-leak-address.log

LINES=`wc -l $PID-leak-address.log|egrep -o '^[0-9]+'`

if [ -f /tmp/$PID-mem-leak.log ];
then
    rm /tmp/$PID-mem-leak.log;
fi

cat $PID-leak-address.log | while read LINE_LEAK
do
    cat $PID-mem.log|grep $LINE_LEAK -n -m 1 -C 3 >> /tmp/$PID-mem-leak.log
    echo -e "\n--------------------------------------------------------------\n" >> /tmp/$PID-mem-leak.log
done

cp /tmp/$PID-mem-leak.log $PID-mem-leak.log

echo "find memory leak: $LINES, check file $PID-leak-address.log and $PID-mem-leak.log"

参考链接
http://www.opensips.org/Documentation/TroubleShooting-OutOfMem

Tags: memory leak opensips 内存泄露

发表评论

电子邮件地址不会被公开。 必填项已用*标注