Posted
Filed under Computer/Linux

VmPeak:     4772 kB
VmSize:     4772 kB
VmLck:         0 kB
VmHWM:       412 kB
VmRSS:       412 kB
VmData:     1192 kB
VmStk:        88 kB
VmExe:         4 kB
VmLib:      1408 kB
VmPTE:        40 kB
StaBrk: 00601000 kB
Brk:    03471000 kB
StaStk: 7fffb21d3c00 kB
Threads:        1
allocated : 5

( 여기서 VmRSS 데이터 크기가 계속 늘어난다면 이 프로그램에는 memory leak 현상이 있다고 볼수 있다. )

* VmPeak: Peak virtual memory size. ("high water mark")
* VmSize: Virtual memory size
* VmLck : Locked virtual memory size
* VmHWM: Peak resident set size ("high water mark").
* VmRSS : Resident Set size ( usage memory size )
* VmStk : allocated static memory ( like as, “char static[102];” )
* VmData : allocated dynamic memory (like as, “char *p; p=malloc(1024*1024); “)
* VmLib : memory size of linked Shared library
* Threads : number of threads of application.
* allocated : virtual memory를 allocated 한 숫자.
처음 프로그램 실행하면 최초 값들이 잡히는데 그 숫자보다 바뀔때 의미가 있음.

malloc으로 메모리를 할당하면 VmData가 늘어남. 즉 메모리에 할당만 해둠 (실제 메모리를 그만큼 차지하지 않고 얼마만큼 쓰겠다고 할당만 시켜둠, OOM이 작동될때는 할당된 메모리는 이미가 없고 실제 사용된 메모리가 너무커 쓸수있는 메모리가 없을때 OOM일 실행됨.)
그러나 free로 할당을 풀면 다시 VmData는 줄어들음.

이렇게 malloc으로 잡고 free로 풀고 하다가 가끔 allocated 숫자가 올라가면 그 숫자가 올라간만큼 VmData 크기는 free로 풀었을지라도 내려가지 않고 그 숫자만큼 메모리 할당을 유지시킴.
만약에 메모리 사용을 이 할당된 메모리보다 적게 쓰면 VmData는 커지지 않지만 이보다 더 할당하면 다시 커지고 free를 시키면 줄어들지만 allocated 된만큼 VmData가 늘어나 있는데 까지만 줄어들게됨.

allocated 숫자가 자꾸 커지면 VmData 크기도 커지면서 다시는 그아래로 줄어들지 않는다.
allocated 숫자가 커지는 이유는 모르겠음.

VmRSS는 VmData 로 할당한 공간내에 데이터를 넣게되면 늘어나는 공간으로 실제 메모리를 쓰고 있는 양임.
VmSize, VmRSS, VmData는 free를 하면 free 된만큼 줄어든다.

VmRSS는 malloc으로 할당하면 할당하는데 들어가는 index정도의 작은 크기만큼만 size가 늘어남. 나중에 malloc으로 할당한 공간에 데이터를 넣으면 그만큼 VmRSS size가 커짐. 그리고 free를 하면 데이터가 사라지는 만큼만 줄어듬.

VmData는 malloc으로 할당하면 할당됀 공간만큼 size가 늘어남.
VmSize는 VmData + VmLib + VmExe + VmStk + VmPTE + something. 크기임.

mem.sh script
-----------------------------------------------------------------------
# cat mem.sh
[code]
if ps -ef |grep "./a.out" |grep -v grep >/dev/null; then
  cat /proc/$(ps -ef |grep "./a.out" | grep -v grep |awk '{print $2}')/status |grep "kB$"
  cat /proc/$(ps -ef |grep "./a.out" | grep -v grep |awk '{print $2}')/status |grep "^Threads:"
  echo "allocated : $(cat /proc/$(ps -ef |grep "./a.out" | grep -v grep |awk '{print $2}')/maps | awk '{if($6==NULL) print}' | wc -l )"
fi
[/code]
-----------------------------------------------------------------------

memory leak을 없애기 위한 한가지 idea!!

[code]
#include <stdio.h>
#include <stdlib.h>

#define MB 1024*1024
int main(int argc,char *argv[]) {
   void *bnkblock=NULL;
   int count=0;
   int add=0;
   int skip=0;
   while (1) {
      sleep (10);
      ++count;
      // malloc 하기전에 변수가 할당됐다면 free를 시키고 malloc하게 만듬.
      if(bnkblock) {  
           printf("free allocating 1 MB\n");
           free(bnkblock);
           sleep (5);
      }
      bnkblock=(void *) malloc(MB);
      if (!bnkblock) break;
      printf("current allocating %d MB\n",count);
   }
   exit(0);
}
[/code]

memory leak은 아래처럼 하면 생긴다.
[code]
char *a;
a=malloc(1024);  //처음 할당.
a=malloc(2048); //위의 메모리(1024)는 leak되고 2048을 새로 할당함.
free(a);  // 2048에 대해서만 free 시키고 1024는 그냥 leak 된상태로 남는다.
[/code]

free or g_free 함수는 할당된 메모리의 데이터 영역을 반환하여 데이터를 없애는것이지 그 변수의 정의를 없애는것이 아니므로 if(bnkblock) 함수는 처음 한번은 적용된다. 즉, bnkblock에 malloc을 한번 사용하면 bnkblock 변수는 존재하게 되므로 다음부터 if(bnkblock) 는 의미가 없어진다. 즉, "if(bnkblock) { ...; free(bnkblock); ...  }" 을 쓴것이나 그냥  "free(bnkblock);" 를 쓴것이나 같아진다. if함수가 의미가 없어진다. 즉 실수로 for 같은 loop를 시키게되면 free를 두번 이상 하게된것과 같아 core dump떨어지며 죽게된다.
 
그래서 다음처럼 코드를 바꿔줘야한다.
(data를 free로 날렸으면 변수역시 초기화 해줘야만 if(bnkblock) { ...; free(bnkblock); ...  } 구문이 의미가 있어진다. )
[code]
#include <stdio.h>
#include <stdlib.h>

#define MB 1024*1024
int main(int argc,char *argv[]) {
   void *bnkblock=NULL;
   int count=0;
   int add=0;
   int skip=0;
   int a=0;
   while (1) {
      sleep (10);
      ++count;
          if(bnkblock) {
              printf("exist\n");
          } else {
              printf("nothing\n");
          }
sleep(2);
      if(bnkblock) {
           printf("free allocating 1 MB\n");
           free(bnkblock);
//    bnkblock=NULL; //NULL or 0으로 변수 자체도 초기화 해줘야 한다.
    bnkblock=0;
           sleep (2);
      } else {
          printf("not free\n");
          sleep (2);
          bnkblock=(void *) malloc(MB);
          if (!bnkblock) break;
          printf("current allocating %d MB\n",count);
      }
   }
   exit(0);
}
[/code]

upgrade code

[code]
#include <stdio.h>
#include <stdlib.h>

#define MB 1024*1024
void * k_free(char *);

int main(int argc,char *argv[]) {
   void *bnkblock=NULL;
   int count=0;
   int add=0;
   int skip=0;
   int a=0;
   while (1) {
      sleep (10);
      ++count;
          if(bnkblock) {
              printf("exist\n");
          } else {
              printf("nothing\n");
          }
sleep(2);
      if(bnkblock) {
           printf("free allocating 1 MB\n");
//이것이 약간 변수 free 시킬때 편할수 있다.
           bnkblock=k_free(bnkblock);
           sleep (2);
      } else {
          printf("not free\n");
          sleep (2);
          bnkblock=(void *) malloc(MB);
          if (!bnkblock) break;
          printf("current allocating %d MB\n",count);
      }
   }
   exit(0);
}

void * k_free(char *p) {
     free(p);
     return NULL;
}
[/code]

2009/12/18 13:25 2009/12/18 13:25
[로그인][오픈아이디란?]