zoukankan      html  css  js  c++  java
  • aix内存泄露

    介绍使用脚本判断内存泄漏的简便方法
      
    Document #: 2811995H29001 
    Body: 
    [标题] 
    介绍使用脚本判断内存泄漏的简便方法
    内容提要:
    本文份四个部分介绍如何使用提供的脚本定位分析应用内存泄漏 
    一,前言
    二,内存使用介绍
    三,脚本使用介绍
    四,示例分析
    五,总结
    说明: 
    介绍使用脚本判断内存泄漏的简便方法 
    一,前言 
    应用内存泄漏是UNIX 系统中比较常见的一种现象,如何定位并确定内存泄漏的
    应用是一个相对复杂的过程。本文将探讨内存泄漏的产生,及在AIX 系统中如何利用
    提供的脚本,在系统级层面判断内存泄漏的进程。
    二,内存使用介绍 
    C 语言中,应用使用malloc() 函数从进程的堆栈中申请内存,而在C++ 中内存的申请
    使用是在类的初始化中通过构造函数建立的,包含类及其成员。当进程不再需要部
    分内存是,将通过系统free() 函数归还给操作系统,而在C++ 中则通过析构函数释放
    类的内存。进程终止时,进程的使用的栈的内存将全部归还给操作系统。如果进程
    申请使用的内存不能释放,而且进程堆栈持续增长,应用可能存在内存泄漏。最终
    的结果是进程消耗所有的系统内存,导致应用异常终止,或者是系统启动自身的保
    护机制杀掉进程,进而释放系统的内存。
    操作系统开发者不断的探求如何更有效的使用、分配内存的策略,在AIX 4.2 – 
    5.2 版本中,使用Yorktown 机制分配系统内存,相对于以前的版本,AIX 5.3 中引入
    了新的内存分配使用机制watson ,基于rbtree(red-black tree) 结构,提高了malloc 的
    性能,同时减少了堆栈的碎片。
    三,脚本使用介绍 
    本文提供一组脚本,通过这组脚本,可以比较简单、快速的判断定位,哪一个进程
    产生内存泄漏。脚本名称post_vg.sh ,使用方法如下:
    1) 首先搜集系统的初始状态,包含每个进程使用的内存情况: 
    # ps vg > ps.before 
    2) 间隔一段合适的时间后,如15 分钟,根据应用或系统的情况而定,重新收集系统的状态 
    # ps vg > ps.after 
    3) 比较系统的前后状态,判断进程的内存使用情况,输出信息中Delta 表明进程内存的前后
    使用情况,如果值增加,其中一个可能的情况就是内存泄漏 
    # ./post_vg ps.before ps.after 
    脚本的内容如下:
    #!/bin/ksh 
    # Correlate ps.before and ps.after data .. 
    # command output from ps vg 
    ONE_FILE=temp_ps_vg 
    print_help() { 
    print "Version 1.0" 
    print "Usage: post_vg.sh [single_file|before_ps after_ps]" 
    print " Post process ps vg output " 
    print " " 
    print " where, " 
    print " single_file contains a before and after snapshot" 
    print " " 
    print " No files specified - assume" 
    print " ==> ps_vg.before " 
    print " ==> ps_vg.after " 
    exit -1 
    main() { 
    if [[ $1 == "-?" ]] 
    then 
    print_help 
    exit -1 
    fi 
    if [[ $# == 2 ]] 
    then 
    cat $1 $2 > $ONE_FILE 
    elif [[ $# == 1 ]] 
    then 
    cat $1 > $ONE_FILE 
    else 
    cat ps_vg.before ps_vg.after > $ONE_FILE 
    fi 
    post_vg 
    rm $ONE_FILE 
    post_vg() { 
    cat $ONE_FILE | awk 'BEGIN { 
    list_label = "None" 
    /PID/ { 
    if( list_label == "None" ) 
    list_label = "Before" 
    else 
    list_label = "After" 
    next 
    pid_list[$1] 
    pid_size[$1, list_label ] = $6 
    pid_name[$1] = $13 
    END { 
    printf("%15s\t%10s\t%11s\t%10s\t%10s\n", "pid", \ 
    "Name", \ 
    "Before Size", \ 
    "After Size", \ 
    "Delta") 
    for( pid in pid_list ) { 
    if( (pid,"Before") in pid_size && (pid,"After") in pid_size ) { 
    delta = pid_size[pid, "After"] - pid_size[pid, "Before"] 
    d_total += delta 
    printf("%15s\t%10s\t%11d\t%10d\t%10d\n", \ 
    pid, \ 
    pid_name[pid], \ 
    pid_size[pid, "Before"], \ 
    pid_size[pid, "After"], \ 
    delta ) 
    printf("*** Total Delta %d\n", d_total) 
    }' 
    main $@ 
    四,示例分析 
    通过以下的简单应用,借助以上的脚本,分析系统内存的使用。
    测使用例:
    #include <stdio.h> 
    main() { 
    char *ptr; 
    int count=0; 
    /* 申请系统内存 */ 
    for (count=0; count<100000; count++) { 
    ptr = (char *)malloc(1024*1024); 
    memset(ptr, 0, 1024*1024); 
    /* 释放系统内存,决定应用是否产生内存泄漏。如果生成内存泄漏的应用,需要打开注释 */ 
    /* free(ptr); 
    */ 
    sleep(1); 
    编译链接以上程序,生成有内存泄漏和没有内存泄漏两种情况,应用名称如下:
    memleak : 有内存泄漏
    nmemleak :没有内存泄漏
    测试如下:
    1) 测试应用没有内存泄漏
    a) 运行nmemleak程序 
    # nmemleak
    b) 使用命令ps收集系统的状态 
    # ps vg >ps.before
    c) nmemleak运行一段时间后,假定30秒,重新收集系统的状态 
    # ps vg >ps.after
    d) 使用post_vg.sh分析状态文件,并查看Delta项是否为0 
    # ./post_vg.sh ps.before ps.after
    输出结果如下:
    pid Name Before Size After Size Delta
    ... ... 
    284 wait 40 40 0
    192946 /usr/sbi 1300 1300 0
    168240 nmemleak 1120 1120 0 
    119182 /usr/sbi 772 772 0
    57792 /usr/sbi 640 640 0
    ... ...
    *** Total Delta 0 
    从上面的分析结果可以看出,Delta项值为0,也就是说,可以基本断定nmemleak没有内存泄漏。
    2) 测试应用有内存泄漏
    a) 运行memleak程序 
    # memleak
    b) 使用ps命令收集系统的初始状态 
    # ps vg >ps.before
    c) memleak运行一段时间后,假定30秒,重新运行ps命令收集系统的状态 
    # ps vg >ps.after
    d) 使用post_vg.sh分析状态文件,查看Delta项 
    # post_vg.sh ps.before ps.after
    查卡分析结果如下:
    pid Name Before Size After Size Delta 
    ... ... 
    90456 /usr/ccs 128 128 0 
    110734 /usr/sbi 1520 1520 0 
    209368 telnetd 624 624 0 
    168274 memleak 13408 42080 28672 
    147862 /usr/sbi 212 212 0 
    36882 pilegc 144 144 0 
    115076 /usr/sbi 1040 1040 0 
    78120 rpc.lockd 204 204 0 
    284 wait 40 40 0 
    ... ... 
    *** Total Delta 28672 
    分析以上结果,可以看到,memleak 应用使用的进程内存增加了28672K 字节,明显存在内存
    泄漏。接下来,要做的是定位应用那个函数造成的内存泄漏,需要按行定位代码,或者使用
    第三方的内存检测工具,如Purify 。
    五,总结 
    决定于应用的复杂程度,确定和定位内存泄漏,难度会相应的不同,结合系统提供的其他工具, 
    如svmon ,和更专业的内存使用分析工具判断应用内存的使用情况。
     
  • 相关阅读:
    电源
    SM2947
    网表
    cadence设计思路
    青山依旧在,几度夕阳红
    乐观锁与悲观锁
    笔记
    强弱软虚引用
    缓存相关
    dubbo
  • 原文地址:https://www.cnblogs.com/hbt19860104/p/2626637.html
Copyright © 2011-2022 走看看