메모리는 시스템이 연산할 공간을 제공해주는 리소스이다. 메모리가 부족하면 시스템은 응답 불가 현상에 빠지거나 큰 성능 저하를 일으킬 수 있다.
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
으로 시작되는 첫 행을 해석해보자
free
영역보다 값이 큰 이유는 사용 영역이 충분히 커진 어느 시점부터는 커널이 buff/cache 용도로 사용하던 영역을 어플리케이션을 위해 반환하기 때문이다.Swap
으로 시작되는 두번째 행을 해석해보자
블록 디바이스(Block Device)란 하드 디스크나 CD/DVD 등의 장치를 말하며 블록이나 섹터등의 단위로 데이터를 전송한다. 커널은 이 블록 디바이스라고 불리는 디스크로부터 데이터를 읽거나 사용자의 데이터를 디스크에 저장한다. 이 때 I/O 속도의 향상을 위해서 메모리의 일부를 디스크에 대한 캐싱 영역으로 사용하는데, 그 캐싱 영역이 바로 buff/cache
영역이다.
buff/cache에서 buff
부분은 Buffer Cache를 의미한다. Buffer Cache는 파일 시스템의 메타 데이터를 담고 있는 블록을 저장하고 있는 캐시이다. 또한 cache
부분은 Page Cache이며, 읽어온 파일 내용이 저장되는 캐시이다.
프로세스가 메모리를 쓰다보면 buff/cache 영역으로 사용하던 메모리도 거의 반환되어 사용할 메모리가 없어지는 순간이 발생한다. 시스템은 이 때부터 swap
이라는 영역을 사용하게 된다.
swap이란 하드 디스크의 일부를 메모리로 사용하는 가상 메모리 기술이다. swap을 사용하게 되면 하드 디스크와 통신하는 I/O가 정체 구간이 되어 시스템의 성능이 줄어들 가능성이 있다.
위에서 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 명령어에서 얻을 수 있는 정보를 제외한 것들 중에서 주목해볼만한 내용은 다음과 같다.
Active/Inactive를 나누는 기준은 LRU(Least Recently Used)이다. 이 알고리즘으로 가장 최근에 쓰였던 데이터는 메모리 영역에 남고 자주 쓰이지 않아 우선순위가 밀린 데이터들은 swap으로 이동하게 된다.
커널 역시 프로세스이기 때문에 메모리를 필요로 한다. slab
영역은 커널이 사용하는 메모리 공간으로서 조금 특별한 방법으로 메모리를 할당받아서 사용한다.
Slab: 44860 kB
SReclaimable: 18316 kB
SUnreclaim: 26544 kB
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 영역 중 가장 많이 사용되는 캐시는 dentry
와 inode_cache
이다. dentry 캐시는 디렉터리의 계층 관계를 저장해둔다. 예를 들어서 cd
명령어나 ls
명령어로도 dentry 캐시는 증가될 수 있다. inode_cache는 파일의 inode에 대한 정보를 저장해두는 캐시이다.
slab 영역은 free 명령어에서 used로 계산된다. 그렇기 때문에 간혹 프로세스들이 사용하는 메모리 영역을 모두 더하고도 used와 맞지 않을 경우 slab 메모리에서 누수가 발생하는 것일 수도 있다.