145주차 /proc/meminfo 로 알아 본 리눅스의 메모리에 대하여


#1

커널의 메모리 관리에 대하여

145주차 커널 스터디는 start_kernel()의 여러 단계 중에 page_writeback_init()을 분석하고 있습니다.

여기에서 global_dirtyable_memory() 를 구하는 중에 커널의 메모리 관리를 어떻게 하는지? 에 대하여 정리 한것입니다. 리눅스 커널의 메모리 관리를 전부 보는 것은 따로 할 것이며, 여기서는 우선 /proc/meminfo 가 의미하는 것을 설명하겠습니다.

프로그램은 메모리에서 실행한다.

우리가 사용하는 리눅스는 폰 노이만 구조로 어떤 프로그램이 실행하려면 메모리에 실행할 코드와 사용할 데이터가 메모리에 있어야 합니다. 메모리에 실행할 코드와 처리할 데이터를 읽어 오는 과정과 다 처리된 데이터를 저장 장치에 쓰는 과정이 필요로 합니다.

즉 프로그램이 실행한다는 것은 저장 장치 -> buffer -> cache -> memory 로 저장된 데이터가 이동합니다.

uname -a // 시스템에 기본 정보 알아보기, 속칭 “너 누구냐?”

우리가 사용하는 시스템의 정보를 uname -a 로 알아봅니다.

[email protected]:~$ uname -a
Linux Neuromancer 4.2.0-35-generic #40~14.04.1-Ubuntu SMP Fri Mar 18 16:37:35 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

시스템은 ubuntu-14.04 를 설치하였고, 최신 시스템을 업데이트 하면 리눅스 커널 4.2.0-35-generic 이라는 것을 알수 있습니다.

cat /proc/meminfo // 메모리 정보 보기

터미널에서 cat /proc/meminfo를 입력하면, 지금 사용하는 시스템의 메모리 정보를 알려줍니다.

[email protected]:~$ cat /proc/meminfo
MemTotal:       16373480 kB
MemFree:        15579944 kB
MemAvailable:   15912836 kB
Buffers:           44224 kB
Cached:           325624 kB
SwapCached:            0 kB
Active:           448776 kB
Inactive:         188136 kB
Active(anon):     267628 kB
Inactive(anon):     8916 kB
Active(file):     181148 kB
Inactive(file):   179220 kB
Unevictable:          32 kB
Mlocked:              32 kB
SwapTotal:      16715772 kB
SwapFree:       16715772 kB
Dirty:               244 kB
Writeback:             0 kB
AnonPages:        267144 kB
Mapped:           206988 kB
Shmem:              9484 kB
Slab:              49980 kB
SReclaimable:      25636 kB
SUnreclaim:        24344 kB
KernelStack:        4736 kB
PageTables:        14692 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:    24902512 kB
Committed_AS:    1748384 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      141488 kB
VmallocChunk:   34359537660 kB
HardwareCorrupted:     0 kB
AnonHugePages:     55296 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      114276 kB
DirectMap2M:    16603136 kB

중요한 것들의 보면서 그 의미를 이야기 하겠습니다.

MemTotal, MemFree

먼저 전체 메모리와 사용 할 수 있는 메모리가 표시됩니다.

MemTotal: 16373480 kB

MemFree: 15579944 kB

커널이 인식한 메모리는 MemTotal은 16373480 kB (약 16기가) 라고 나옵니다.

커널이 사용 할 수 있는 빈 메모리 (MemFree)는 15579944 kB (약 15기가)라고 나옵니다.

전체 메모리는 어떻게 구성되는 가?

MemTotal = MemFree + File-backed memory + Anonymous memory+ kernel space memory

  • 전체 메모리는 커널이 사용할 수 있는 메모리 영역과 사용자가 사용할 수 있는 메모리 영역으로 나눕니다.
  • MemTotal = MemFree + User space memory + kernel space memory
  • 그리고 사용자(User) 영역에서 사용하는 메모리는 File-backed 으로 사용된 메모리 +Anonymous 한 메모리 입니다.
    • User Memory = File-backed memory + Anonymous memory

File-backed memory

사용자가 실행하는 프로그램은 메모리에서 실행되기 때문에, 실행 프로그램이나 프로그램이 사용하는 데이터를 저장 공간에서 읽어 와야합니다.

저장 장치는 파일이라는 개념을 사용합니다. file에는 저장된 프로그램의 정보나 데이터, 크기, i-node 위치와 같은 메타 정보와 실제 데이터로 구성됩니다.

file에서 읽어 왔거나 앞으로 다시 file로 저장될 것들을 file-backed memory 영역으로 해서 메모리 관리자가 관리합니다.

  • Buffers, Cached, SwapCached 란? file-backed memory에는 buffers, cached, swapCached 가 있습니다. 예시에서는 다음처럼 표시 되었네요.

Buffers: 44224 kB

Cached: 325624 kB

SwapCached: 0 kB

Anonymous memory

메모리에 있으나 file에서 오지 않았으며, 앞으로도 File에 쓰여지지 않을 것들을 Anonymous memory로 해서 관리합니다. 정리하면 :

  • file에서 읽어 왔거나 앞으로 다시 file로 저장될 것들을 file-backed memory
  • memory 에 있지만 file로 쓰여지지 않은 영역은 Anonymous memory

Active 과 Inactive 이란.

메모리에서 지금 실행하는 프로그램이나 앞으로 실행할 프로그램을 커널은 Active로 메타정보에 표시해서 관리합니다.

Acitve: 실행 중인 프로그램이나 데이터 , 그리고 실행할 예정인 프로그램이나 데이터 Inactive: 실행 하지 않고 대기 중인(비활성) 프로그램이나 데이터

Active 에는 Anonymous 와 File-backed memory가 있으며, Inacitve에도 Anonymous 와 File-backed memory가 있습니다.

Active: 448776 kB

Inactive: 188136 kB

Active(anon): 267628 kB

Inactive(anon): 8916 kB

Active(file): 181148 kB

Inactive(file): 179220 kB

Swap

어떤 프로세스가 활성화 되었을 때 메모리가 부족하면 비활성화(Inactive)로 된 것을 보조 저장장치에 메모리의 데이터를 일부 저장해 놓고, 실행할 프로세스가 사용할 메모리 공간을 확보한 후 실행합니다. 이것을 스왑이라고 하는데요. 이 스왑을 할때 사용하는 memory 영역입니다.

SwapTotal: 16715772 kB

SwapFree: 16715772 kB

Dirty , Writeback

프로세스가 실행 중에 데이터가 처리되어 바뀌었다면, Dirty라고 메타 데이터에 표시합니다. 그리고 Dirty는 보조 저장장치에 저장될 때 Writeback으로 바뀌어 저장 하는 과정을 따릅니다.

Dirty: 244 kB

Writeback: 0 kB

Shmem

여러 프로세스가 공유하는 메모리 영역을 Shmem이라고 합니다.

예를 들어 동일한 프로세스가 여러개 실행되었다면 실행 코드는 동일하고, 각각의 프로세스가 사용하는 데이터만 다르게 하면 메모리를 절약할 수 있습니다. 이러한 것을 이용할 때 Shmem을 사용합니다.

AnonPages: 267144 kB Mapped: 206988 kB

Shmem: 9484 kB

KernelStack

커널에서 프로세스가 전환등이 일어날때 Stack에 현재 상태를 저장하는데 이때 사용하는 메모리 영역입니다.

KernelStack: 4736 kB

PageTables

메모리는 MMU (Memory Management Unit)으로 관리하며, 실제 물리 메모리와 가상 메모리간 주소 변환을 하며서 사용합니다. 주소 변환을 할때 page라는 단위로 메모리를 조각내서 사용하며 이 page 정보를 담고 있는 메타데이터를 Page table이라고 합니다. X86 64비트라면 3단계 Page Table을 사용합니다.

PageTables: 14692 kB

Vmalloc

실제 물리 메모리가 아닌 가상 메모리를 사용해서 프로세스가 실행되며, 이때 가상 메모리를 할당, 비 할당합니다. 이를 Vmalloc이라고 합니다.

VmallocTotal: 34359738367 kB

VmallocUsed: 141488 kB

VmallocChunk: 34359537660 kB