zoukankan      html  css  js  c++  java
  • 关于进程exit后,内存释放释放的实践

    最近碰到一个问题,或许也是小猿们都会碰到的问题:内存泄露。

    都知道malloc后需要free才能释放内存,shmat后需要shmdt才能断掉内存区并使用IPC_RMID命令删除共享内存。那么如果是当前进程exit后,这些东西还需要收到清理吗?进程退出会清理除打开的文件描述符外,还做些什么呢?

    代码:

    思路:在进程中申请内存空间不释放,进程退出,查看当期是否有内存释放

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <unistd.h>
     5 #include <errno.h>
     6 #include <signal.h>
     7 #include <sys/ipc.h>
     8 #include <sys/shm.h>
     9 
    10 //在进程中申请内存空间不释放,进程退出,查看当期是否有内存释放
    11 
    12 #define MALLOC_SIZE 1024*100
    13 
    14 
    15 void ChildProcess()
    16 {
    17     char *p = NULL;
    18 
    19     p = (char *)malloc(MALLOC_SIZE);//100k
    20 
    21     if(!p)
    22     {
    23         printf("error to malloc   %s
    ",strerror(errno));
    24     }
    25 
    26     memset(p,0,MALLOC_SIZE);
    27     p[0] = 'M';
    28     printf("=======%p     %c======
    ",p,p[0]);
    29 
    30 
    31     p = NULL;
    32 
    33     int shmid = shmget(IPC_PRIVATE,MALLOC_SIZE,IPC_CREAT|SHM_R|SHM_W);
    34 
    35     p = shmat(shmid,NULL,0);
    36 
    37     memset(p,0,MALLOC_SIZE);
    38     p[0] = 'S';
    39     printf("###########%p        %c###########
    ",p,p[0]);
    40 
    41     exit(0);
    42 }
    43 
    44 
    45 int main(void)
    46 {
    47     int i = 0;
    48     int ret = 0;
    49     signal(SIGCLD, SIG_IGN);
    50     while(++i < 100)
    51     {
    52         ret = fork();
    53 
    54         if(ret == 0)//child
    55         {
    56             ChildProcess();
    57         }
    58         else if(ret > 0 )//father
    59         {
    60             printf("i have create %d proceses !!
    ",i);
    61             sleep(1);
    62         }
    63         else
    64         {
    65             printf("error to create process   %s 
    ",strerror(errno));
    66         }
    67     }
    68 
    69 
    70 
    71     return 0;
    72 }

    编译运行结果:

    [root@localhost UtilLibs]# gcc -o test_leak_memory test_leak_memory.c 
    [root@localhost UtilLibs]# ./test_leak_memory                         
    i have create 1 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 2 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 3 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 4 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 5 proceses !!
    i have create 6 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 7 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 8 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 9 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 10 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 11 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 12 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 13 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 14 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 15 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 16 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########
    i have create 17 proceses !!
    =======0x16c0010     M======
    ###########0x7fb9547db000               S###########

    同时,通过ps aux | grep test,得到PID,用命令pmap查看该进程内存使用情况:

    [root@localhost ~]# pmap 43492
    43492:   ./test_leak_memory
    0000000000400000      4K r-x--  /mnt/hgfs/e/Lessons/MyExercise/UtilLibs/test_leak_memory
    0000000000600000      4K rw---  /mnt/hgfs/e/Lessons/MyExercise/UtilLibs/test_leak_memory
    000000317c800000    136K r-x--  /lib64/ld-2.14.90.so
    000000317ca21000      4K r----  /lib64/ld-2.14.90.so
    000000317ca22000      4K rw---  /lib64/ld-2.14.90.so
    000000317ca23000      4K rw---    [ anon ]
    000000317cc00000   1716K r-x--  /lib64/libc-2.14.90.so
    000000317cdad000   2048K -----  /lib64/libc-2.14.90.so
    000000317cfad000     16K r----  /lib64/libc-2.14.90.so
    000000317cfb1000      8K rw---  /lib64/libc-2.14.90.so
    000000317cfb3000     20K rw---    [ anon ]
    00007fd69545d000     12K rw---    [ anon ]
    00007fd695475000      8K rw---    [ anon ]
    00007fffcaf8d000    132K rw---    [ stack ]
    00007fffcafff000      4K r-x--    [ anon ]
    ffffffffff600000      4K r-x--    [ anon ]
     total             4124K

    结果:

    1. 进程退出后,下一个进程重新申请的地址和上一个进程中申请的地址是相同的,也就是说应该是从堆上同一块区域分配使用的。

    2. pmap显示,进程的total消耗是不变的。

    那么,结论是否可以定为:在多进程编程中,如果子进程主动调用了exit来终止自己,那么该子进程中手动申请的内存就不需要再手动释放啦。欢迎大家交流讨论。

  • 相关阅读:
    配置文件配置网络
    安装Linux centos 7.3
    java二维字符数组的输入
    前端保存JSON文件到本地
    在Springboot中使用swagger2
    Vue better-scroll使用指南
    解决端口占用问题
    CheckSum(校验和)计算
    区分按字寻址与按字节寻址
    进制转换
  • 原文地址:https://www.cnblogs.com/xiaowenhu/p/3542535.html
Copyright © 2011-2022 走看看