最近碰到一個問題,或許也是小猿們都會碰到的問題:內存泄露。
都知道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\n",strerror(errno)); 24 } 25 26 memset(p,0,MALLOC_SIZE); 27 p[0] = 'M'; 28 printf("=======%p %c======\n",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###########\n",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 !!\n",i); 61 sleep(1); 62 } 63 else 64 { 65 printf("error to create process %s \n",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來終止自己,那么該子進程中手動申請的內存就不需要再手動釋放啦。歡迎大家交流討論。