zoukankan      html  css  js  c++  java
  • 一种内存泄露检查和定位的方法(转)

    原文链接:https://blog.51cto.com/xiamachao/1929118

    一个系统后台服务进程,可能包括多个线程,在生成环境下要求系统程序能够稳定长时间稳定运行而不宕机。其中一个基本的前提就是需要保证系统程序不存在内存泄露。那么,该如何判读系统程序是否存在内存泄露呢?如果存在,又该如何检测呢?

    0.判读系统程序是否存在内存泄露

    对于频繁快速申请内存的应用,可以允许下面的命令:

    top -p `pidof YourProgrogram`

    如果看到系统内存使用率一直上身,没有下降,就说明很可能存在内存泄露。

    对于申请、使用内存比较缓慢的应用程序,可以通过下面的命令,观测一天乃至一周内内存使用率的变化:

    for ((i=0;i<100000;i++)); do pidstat -p `pidof YourProgram` -tr | tee -a thread_mem_static.txt; sleep 10; done

    如果上面显示的RSS的内存随着时间推移不断增加,且不符合程序预期,那么很可能存在内存泄露。

    1.定位内存泄露的线程或代码位置

    检查主进程的每个线程的page fault的频率,虽然page fault频率高的不一定有内存泄露,但有内存泄露的线程的page fault的频率一定很高。而体现每个线程Page fault频率的指标就是上图中每个线程的minflt/s值,如果它的值一直偏高,就说明该线程反复申请内存或者不停在栈上使用buffer,此时就需要利用gdb打印出每个线程信息,可以参考下面的gdb命令:

    gdb -q --batch --ex "thread apply all bt" -p `pidof tmem`

    根据上面对应的线程号找到相应函数,然后进行跟踪,可以参考下面的示例:

    上图中显示线程14178 (mem_funcs)线程频繁使用新的内存,查看代码,果然存在内存泄露:

    需要强调的是,只有RSS不一直增加,哪怕minflt/s一直增加,也表明没有内存泄露,比如下面的测试程序,频繁使用栈上空间:

    void internal_mem_funcs(void)

    {

    long int test[MAX_BUF_LEN] = {0,};

    //long int * test = (long int *)malloc(MAX_BUF_LEN * sizeof(long int));

    int i = 0;

    for (i = 0; i < MAX_BUF_LEN; i++) {

    test[i] = random();

    }

    return;

    }

    它的pidstat统计图如下:

    2.常见的内存泄露方式

    笔者最近分析了一个系统服务进程内存泄露的问题,下面总结了一些代码中很容易出现内存泄露的地方:

    函数正常成功执行的时候有释放内存,但在执行异常退出的时候,没有释放所有先前申请的内存;

    对类似strdup()/strndup()/g_strdup()的函数的返回值,使用完之后,没有释放内存的意识;

    不同模块或者层次的代码相互调用的时候,没有统一约定好是调用者申请内存、释放内存还是被调用者申请、释放内存,抑或是调用者申请/释放内存,被调用者释放/申请内存,导致后面遗忘释放内存或者重复释放内存;

    Java/c++中对异常处理的流程中,遗忘没有释放内存;

    使用了一些不太熟悉的第三方库代码,对类似句柄、描述符、对象相关的API了解不够深入,导致没有也不知道该如何释放内存。
    -----------------------------------
    ©著作权归作者所有:来自51CTO博客作者存储之厨的原创作品,谢绝转载,否则将追究法律责任
    一种内存泄露检查和定位的方法
    https://blog.51cto.com/xiamachao/1929118

    有时候,不小心知道了一些事,才发现自己所在乎的事是那么可笑。
  • 相关阅读:
    Ajax基本案例详解之$.getjson的实现
    Ajax基本案例详解之$.getjson的实现
    Ajax传递json数据
    Ajax传递json数据
    Ajax基本案例详解之load的实现
    多节点日志数据 数据集成
    crontab 问题分析
    不留文档的某某离开后 审计服务器操作历史
    /cloudmonitor.log 主机监控
    网关会对开发者的接口非业务调用错误做统一处理
  • 原文地址:https://www.cnblogs.com/axjlxy/p/15712710.html
Copyright © 2011-2022 走看看