Memory Overview

메모리는 시스템이 연산할 공간을 제공해주는 리소스이다. 메모리가 부족하면 시스템은 응답 불가 현상에 빠지거나 큰 성능 저하를 일으킬 수 있다.

free

free명령어를 통해 시스템의 전반적인 메모리 상태를 조회해볼 수 있다. 주는 옵션에 따라 데이터 단위를 다르게 볼 수 있다. (b,m,k,g)

$ free -m
              total        used        free      shared  buff/cache   available
Mem:            486         252         119           2         114         191
Swap:             0           0           0

Mem으로 시작되는 첫 행을 해석해보자

  • total: 시스템에 설치되어 있는 메모리의 총량이다.
  • used: 사용되고 있는 메모리의 양이다.
  • free: 아직 사용되고 있지 않은, 사용할 수 있는 메모리의 양이다.
  • shared: 공유 메모리의 양이다.
  • buff/cache: 시스템 커널이 버퍼, 페이지 캐시 용도로 사용하고 있는 메모리의 양이다.
  • available: 메모리에서 사용할 수 있는 양이다. free 영역보다 값이 큰 이유는 사용 영역이 충분히 커진 어느 시점부터는 커널이 buff/cache 용도로 사용하던 영역을 어플리케이션을 위해 반환하기 때문이다.

Swap으로 시작되는 두번째 행을 해석해보자

  • total: swap 영역의 전체 용량을 보여준다.
  • used: swap 영역 중 실제로 사용하고 있는 영역에 대한 정보이다.
  • free: swap 영역 중 사용하지 않은 영역에 대한 정보이다.

buff/cache

블록 디바이스(Block Device)란 하드 디스크나 CD/DVD 등의 장치를 말하며 블록이나 섹터등의 단위로 데이터를 전송한다. 커널은 이 블록 디바이스라고 불리는 디스크로부터 데이터를 읽거나 사용자의 데이터를 디스크에 저장한다. 이 때 I/O 속도의 향상을 위해서 메모리의 일부를 디스크에 대한 캐싱 영역으로 사용하는데, 그 캐싱 영역이 바로 buff/cache 영역이다.

buff/cache에서 buff 부분은 Buffer Cache를 의미한다. Buffer Cache는 파일 시스템의 메타 데이터를 담고 있는 블록을 저장하고 있는 캐시이다. 또한 cache 부분은 Page Cache이며, 읽어온 파일 내용이 저장되는 캐시이다.

Swap

프로세스가 메모리를 쓰다보면 buff/cache 영역으로 사용하던 메모리도 거의 반환되어 사용할 메모리가 없어지는 순간이 발생한다. 시스템은 이 때부터 swap이라는 영역을 사용하게 된다.

swap이란 하드 디스크의 일부를 메모리로 사용하는 가상 메모리 기술이다. swap을 사용하게 되면 하드 디스크와 통신하는 I/O가 정체 구간이 되어 시스템의 성능이 줄어들 가능성이 있다.

/proc/meminfo

위에서 free 명령으로 간략한 메모리의 사용 정보를 알 수 있었다. 하지만 free는 그 이상으로 메모리가 어떻게 사용되고 있는지 구체적인 정보를 전달하지 않는다. 그럴 때는 /proc/meminfo 파일을 조회하면 된다.

$ cat /proc/meminfo | more
MemTotal:         498372 kB
MemFree:          257528 kB
MemAvailable:     348084 kB
Buffers:           12864 kB
Cached:            76744 kB
SwapCached:            0 kB   // << 
Active:           114012 kB
Inactive:          47768 kB
Active(anon):      75244 kB   // << 
Inactive(anon):     1400 kB   // << 
Active(file):      38768 kB   // << 
Inactive(file):    46368 kB   // << 
Unevictable:        3652 kB
Mlocked:            3652 kB
SwapTotal:             0 kB
SwapFree:              0 kB
Dirty:                 0 kB   // << 
Writeback:             0 kB
AnonPages:         75852 kB
Mapped:            38748 kB
Shmem:              2048 kB
Slab:              44860 kB   // << 
SReclaimable:      18316 kB   // << 
SUnreclaim:        26544 kB   // << 
--More--

free 명령어에서 얻을 수 있는 정보를 제외한 것들 중에서 주목해볼만한 내용은 다음과 같다.

  • SwapCached: swap으로 빠진 메모리 영역 중 다시 메모리로 돌아온 영역을 의미한다.
  • Active/Inactive(anon): Page Cache 영역을 제외한 메모리 영역을 의미한다. 주로 프로세스들이 사용하는 메모리 영역을 지칭할 때 사용된다.
  • Active/Inactive(file): 커널이 I/O 성능 향상을 위해 사용하는 영역을 의마한다. 주로 buff/cached 영역이 여기에 속한다.
  • Dirty: 커널은 기본적으로 I/O 쓰기 요청들을 일정량이 될 때까지 모아뒀다가 한꺼번에 디스크로 명령을 내린다. Dirty 메모리는 이 과정에서 사용되는 메모리 영역이다.

Active/Inactive를 나누는 기준은 LRU(Least Recently Used)이다. 이 알고리즘으로 가장 최근에 쓰였던 데이터는 메모리 영역에 남고 자주 쓰이지 않아 우선순위가 밀린 데이터들은 swap으로 이동하게 된다.

slab

커널 역시 프로세스이기 때문에 메모리를 필요로 한다. slab 영역은 커널이 사용하는 메모리 공간으로서 조금 특별한 방법으로 메모리를 할당받아서 사용한다.

Slab:              44860 kB
SReclaimable:      18316 kB
SUnreclaim:        26544 kB
  • Slab: slab 메모리의 총량을 의미한다.
  • SReclaimable: slab 메모리중 재사용될 수 있는 영역이다. 즉 메모리 부족 현상이 일어나면 프로세스들에 반환될 수 있는 메모리 영역이다.
  • SUnreclaim: 재사용될 수 없는 영역이다. 해제해서 다른 용도로 사용할 수 없다.

slabtop명령어를 통해 slab 메모리가 어떻게 사용되고 있는지 조회해볼 수 있다.

$ slabtop -o | more
 Active / Total Objects (% used)    : 129462 / 138357 (93.6%)
 Active / Total Slabs (% used)      : 4260 / 4260 (100.0%)
 Active / Total Caches (% used)     : 74 / 123 (60.2%)
 Active / Total Size (% used)       : 41850.22K / 44390.77K (94.3%)
 Minimum / Average / Maximum Object : 0.01K / 0.32K / 8.00K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
 27234  27234 100%    0.12K    801       34      3204K kernfs_node_cache
 17955  15647  87%    0.19K    855       21      3420K dentry
 13923  10096  72%    0.10K    357       39      1428K buffer_head
 11620  11491  98%    0.55K    415       28      6640K inode_cache
  8192   8192 100%    0.03K     64      128       256K kmalloc-32
  6144   5483  89%    0.06K     96       64       384K kmalloc-64
  --More--

커널은 메모리를 사용하기는 하지만 다른 프로세스들만큼 큰 영역을 필요로하지 않는다. 그렇기 때문에 메모리 할당 버디 시스템이 주는 4KB를 slab 할당자로 나눠서 메모리 영역을 좀 더 작고 효율적으로 사용한다.

slab 영역 중 가장 많이 사용되는 캐시는 dentryinode_cache이다. dentry 캐시는 디렉터리의 계층 관계를 저장해둔다. 예를 들어서 cd 명령어나 ls 명령어로도 dentry 캐시는 증가될 수 있다. inode_cache는 파일의 inode에 대한 정보를 저장해두는 캐시이다.

slab 영역은 free 명령어에서 used로 계산된다. 그렇기 때문에 간혹 프로세스들이 사용하는 메모리 영역을 모두 더하고도 used와 맞지 않을 경우 slab 메모리에서 누수가 발생하는 것일 수도 있다.

comments powered by Disqus