본문 바로가기
IT 이야기/Android Performance

[Memory Usage] Memory 상태 분석

by KaySeo 2021. 12. 17.
반응형

Android의 경우 Memory Usage를 측정할 때 많이 사용하는 명령어는 adb shell 명령어 중 하나인 dumpsys meminfo 입니다. dumpsys meminfo에 대해서는 다른 포스트를 이용하여 설명하기로 하고 이번에는 Linux에서 제공하는 Memory 확인 명령어인 "free" 와 "/proc/meminfo"에 대해 알아보도록 하겠습니다.

 

먼저 adb shell에서 간단하게 현재 시스템의 메모리 상태를 확인하려면 "free -m" (여기서 -m 옵션은 용량을 MB로 출력하라는 옵션입니다.)명령어를 입력하시면 됩니다. 그러면 아래와 같은 정보가 출력됩니다. 아래 내용을 보면 첫 줄의 값 중 used값인 3508이 사용 중인 메모리이고 free 값인 4173이 사용가능한 메모리로 생각되지만 이는 buffers와 cached에 대한 계산이 되지 않은 값입니다. 커널 내부적으로는 buffers와 cached의 경우 메모리가 부족할 때 언제든지 사용가능하다고 여기기 때문입니다. 그래서 좀더 자세한 값은 그아래  -/+ buffers/cache 구간에서 확인할수 있습니다.

$ free -m
                total        used        free      shared     buffers
Mem:             7681        3508        4173          18          31
-/+ buffers/cache:           3476        4205
Swap:            4095           0        4095

각각의 column 정보의 의미는,

- total : system에서 사용되고 있는 총 메모리의 크기

- used : 사용 중인 메모리의 크기로 used = total - free - buffers - cached 로 계산됩니다.

- free : 사용되지 않는 메모리 크기

- shared : backward compatibility를 위해 보여지는 값으로 무시해도 됩니다.

- buff/cache : 커널 버퍼로 사용되는 메모리와 페이지 캐시와 slab을 합한 메모리 크기로 이 메모리는 애플리케이션이 필요할 때는 반환이 가능합니다.

- available : 애플리케이션이 시작할 때 swapping없이 사용가능한 메모리의 크기

 

실질적인 메모리 사용량을 계산하고 싶을 때는 -/+ buffers/cache row 의 used 나 free 값을 이용해서 계산하면 됩니다.

Memory Usage (%) = used / total * 100 = 3476 /  7681 * 100 = 45.254 (%)

 

adb shell 명령어인 free, top, ps 는 /pco/meminfo를 이용해서 메모리 정보를 출력하고 있습니다. 따라서 보다 자세한 메모리 정보를 확인하기 위해서는 /proc/meminfo를 이용하면 되고, adb shell 에서 "cat /proc/meminfo"를 하면 결과값을 얻을 수 있습니다.

[root@localhost]# cat /proc/meminfo
MemTotal:            16325540 kB // 전체 메모리 크기
MemFree:              5912216 kB // 사용되지 않고 있는 메모리 크기
Buffers:                   538596 kB // buffer_heads에 사용되는 메모리 크기 (ext* 파일시스템이라면 Buffers는 메모리에 저장되어 있는 메타데이터의 크기)
Cached:                7945564 kB // 파일 데이터 캐시에 사용되는 메모리 크기
SwapCached:              3512 kB // 실제 메모리 상에 존재하는 swap 크기
Active:                  4595420 kB // active 메모리 크기
Inactive:                4537624 kB // inactive 메모리 크기 (메모리 반환시 우선적으로 반환될 대상)
Active(anon):            471856 kB // active 메모리 중 anonymous pages 크기
Inactive(anon):          183712 kB // inactive 메모리 중 anonymous pages 크기
Active(file):             4123564 kB // active 메모리 중 mmaped 할당된 크기
Inactive(file):           4353912 kB // inactive 메모리 중 mmaped 할당된 크기
Unevictable:                     0 kB // swap out 할 수 없게 고정된 크기. 커널에서 고정시킨 page와 유저공간에서 Mlocked 된 page의 합
Mlocked:                         0 kB // 유저공간에서 Mlocked로 고정된 page 크기
SwapTotal:              2096476 kB // 전체 swap 크기
SwapFree:               2063212 kB // swap 공간 중 사용가능한 공간 크기
Dirty:                           316 kB // 페이지캐시 데이터 중 디스크에 쓰여지기 위해 대기 중인 크기
Writeback:                       0 kB // 페이지캐시 데이터 중 현재 디스크에 쓰여지고 있지만 완전히 쓰여지지 않은 크기
AnonPages:              645448 kB // anonymous page의 전체 크기
Mapped:                   87704 kB // mmaped로 할당된 페이지 크기. ex) 라이브러리 파일
Shmem:                     6684 kB // shared memory 크기
Slab:                     1071668 kB // 커널에 의해 할당된 크기
SReclaimable:          1018168 kB // 커널에 의해 할당된 것 중 반환가능 한 크기
SUnreclaim:               53500 kB // 커널에 의해 할당된 것 중 반환불가능한 크기
KernelStack:                3160 kB // 커널 stack에 할당된 크기
PageTables:               21876 kB // 시스템의 모든 페이지를 기록하기 위한 메모리 크기
NFS_Unstable:                  0 kB // NFS 페이지 중 서버에 전송되었으나 storage에 커밋되지 않은 크기
Bounce:                          0 kB // 블록 디바이스의 Bounce buffer 크기
WritebackTmp:                 0 kB // FUSE에서 사용되는 writeback 크기
CommitLimit:        10259244 kB // 현재 시스템에 할당할 수 있는 메모리 사이즈
Committed_AS:       2779732 kB // 현재 시스템에 할당되어 있는 메모리 사이즈
VmallocTotal:    34359738367 kB // vmalloc으로 할당할 수 있는 전체 사이즈
VmallocUsed:           303652 kB // vmalloc으로 할당된 사이즈
VmallocChunk:  34359376640 kB // vmalloc으로 할당할 수 있는 가장 큰 연속된 블록의 크기
HardwareCorrupted:           0 kB 
AnonHugePages:       454656 kB // 유저 공간 페이지 테이블에 anonymous huge page로 할당된 크기
HugePages_Total:              0     // hugepages 관련 정보들
HugePages_Free:              0
HugePages_Rsvd:             0
HugePages_Surp:             0
Hugepagesize:            2048 kB
DirectMap4k:             7680 kB // direct mapping 사이즈
DirectMap2M:      16760832 kB

출처 : https://bloodguy.tistory.com/entry/Linux-시스템프로세스-메모리-사용량-확인-check-systemprocess-memory-usage

참고로 출력된 meminfo 정보의 MemTotal 값을 보면 실제 RAM 값보다 더 적은 것을 알 수 있습니다. 이 MemTotal 값은 실제 물리적 메모리에서 커널코드와 일부 예약된 공간을 제외한 값으로 실제 RAM 값보다 더 적은 값으로 출력됩니다.

 

이 /proc/meminfo 정보를 이용해서 System의 Memory Usage를 계산하는 방법은 아래와 같습니다.

https://stackoverflow.com/questions/41224738/how-to-calculate-system-memory-usage-from-proc-meminfo-like-htop

 

How to calculate system memory usage from /proc/meminfo (like htop)

Running the htop command gives you a picture of the memory usage in a format like this: 1.92G/5.83G Question: how should I interpret the values taken from /proc/meminfo in order to calculate

stackoverflow.com

이 stackoverflow 에서 논의되는 내용을 보면 htop 코드를 기준으로 메모리 사용량을 계산할 수 있을 것 같습니다.

https://github.com/hishamhm/htop/blob/8af4d9f453ffa2209e486418811f7652822951c6/linux/LinuxProcessList.c#L802-L833

 

GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'.

htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'. - GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. I...

github.com

아래 github를 확인하면 메모리 사용량을 계산하는 소스코드를 확인할 수 있습니다.

즉, usedMem = MemTotal - MemFree - ( Buffers + ( Cached + SReclaimable - Shmem ) ) 로 계산됩니다.

static inline void LinuxProcessList_scanMemoryInfo(ProcessList* this) {
...
    if (tryRead("MemTotal:", &this->totalMem)) {}
    else if (tryRead("MemFree:", &this->freeMem)) {}
    else if (tryRead("MemShared:", &this->sharedMem)) {}
		 
	if (tryRead("Buffers:", &this->buffersMem)) {}
				  
	if (tryRead("Cached:", &this->cachedMem)) {}
				  
	if (tryRead("Shmem:", &shmem)) {}
				  
	if (tryRead("SReclaimable:", &sreclaimable)) {}
...
    this->usedMem = this->totalMem - this->freeMem;
    this->cachedMem = this->cachedMem + sreclaimable - shmem;
    this->usedSwap = this->totalSwap - swapFree;
}

void Platform_setMemoryValues(Meter* this) {
    ProcessList* pl = (ProcessList*) this->pl;
    long int usedMem = pl->usedMem;
    long int buffersMem = pl->buffersMem;
    long int cachedMem = pl->cachedMem;
    usedMem -= buffersMem + cachedMem;
    this->total = pl->totalMem;
    this->values[0] = usedMem;
    this->values[1] = buffersMem;
    this->values[2] = cachedMem;
}

 

https://github.com/hishamhm/htop/blob/8af4d9f453ffa2209e486418811f7652822951c6/linux/LinuxProcessList.c#L802-L833

 

GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'.

htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'. - GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. I...

github.com

https://github.com/hishamhm/htop/blob/1f3d85b6174f690a7e354bbadac19404d5e75e78/linux/Platform.c#L198-L208

 

GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'.

htop is an interactive text-mode process viewer for Unix systems. It aims to be a better 'top'. - GitHub - hishamhm/htop: htop is an interactive text-mode process viewer for Unix systems. I...

github.com

이는 아래 free 명령에 대한 man pages에서도 확인할 수 있습니다.

used   Used memory (calculated as total - free - buffers - cache)

https://man7.org/linux/man-pages/man1/free.1.html

 

free(1) - Linux manual page

free(1) — Linux manual page FREE(1) User Commands FREE(1) NAME         top free - Display amount of free and used memory in the system SYNOPSIS         top free [options] DESCRIPTION         top free displays the total amount of free and used

man7.org

이를 기준으로 메모리 사용량을 계산하면 아래와 같습니다.

Used Memory = MemTotal - MemFree - (Buffers + (Cached + Sreclaimable - Shmem))= 16325540 - 5912216 - (538596+(7945564+1018168-6684)) = 917680

 

메모리 사용량(%) = Used Memory / Total Memory * 100 = 917680 / 16325540 * 100 = 5.62 (%) 

※ 참고사이트
https://bloodguy.tistory.com/entry/Linux-시스템프로세스-메모리-사용량-확인-check-systemprocess-memory-usage
https://rednine.tistory.com/792
https://stackoverflow.com/questions/41224738/how-to-calculate-system-memory-usage-from-proc-meminfo-like-htop
https://stackoverflow.com/questions/41224738/how-to-calculate-system-memory-usage-from-proc-meminfo-like-htop
https://xinet.kr/?p=1528
https://zetawiki.com/wiki/%EB%A6%AC%EB%88%85%EC%8A%A4_%EB%A9%94%EB%AA%A8%EB%A6%AC_%EC%82%AC%EC%9A%A9%EB%A5%A0_%ED%99%95%EC%9D%B8
https://ssambback.tistory.com/entry/Linux-Memory%EC%9D%98-%EC%83%81%ED%83%9C%EB%A5%BC-%EB%B6%84%EC%84%9D%ED%95%98%EB%9D%BC
http://rousalome.egloos.com/v/9966593
https://stackoverflow.com/questions/1353283/what-does-the-linux-proc-meminfo-mapped-topic-mean
https://linuxize.com/post/check-memory-linux/
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/deployment_guide/s2-proc-meminfo

 

 

반응형