리눅스에서는 시스템의 상태를 살펴볼 수 있는 다양하 명령들이 있는데 그 중에선 top
이 전반적으로 가장 빠르게 확인할 수 있다.
여기서는 top
으로 시스템의 상태를 전반적으로 파악하는 방법과 특히 프로세스와 관련된 값들의 의미가 어떤게 있는지 알아보겠다.
top
명령을 입력하면 다음과 같은 정보를 볼 수 있다.
옵션 없이 입력하면 주어진 Interval (기본 3초) 간격으로 화면을 갱신하면서 보여준다.
- 순간의 top 정보를 확인하기 위해서는
-b
옵션을 사용하면 된다.
나오는 정보는 다음과 같다.
top - 15:54:16 up 7 days, 2:01, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 115 total, 1 running, 114 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.3 st
MiB Mem : 968.9 total, 135.8 free, 371.4 used, 461.8 buff/cache
MiB Swap: 0.0 total, 0.0 free, 0.0 used. 444.3 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 168808 11184 6776 S 0.0 1.1 0:18.18 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
- 현재 서버의 시간과 서버가 얼마나 구동되었는지
- 시스템의 Load Average 는 어느정도 인지 (Load Average 는 이후에 설명하겠다. 간략하게만 말하면 이 수치가 높으면 서버가 많은 일을 하고 있다고 생각하면 된다.)
- 현재 시스템에서 구동 중인 프로세스의 개수와 상태들
- CPU, Mem, Swap 의 사용량들
- 그리고 각 프로세스의 상세한 정보인 PID, 메모리 사용률, 상태, CPU 점유 시간 등의 내용이 나온다.
PR
: 프로세스의 실행 우선순위.NI
: PR 에 부여할 가산점. NI 와 PR 을 더해서 실제 프로세스의 우선순위가 결정된다.VIRT
: 프로세스가 사용하는 Virtual Memory 의 전체 용량을 가리킨다.RES
: 현재 프로세스가 사용하고 있는 실제 메모리의 양을 가리킨다.SHR
: 다른 프로세스와 공유하고 있는 메모리를 나타낸다. 리눅스의 경우에 공통으로 사용하는 라이브러리 같은게 있는데 이게 이 메모리의 영역이 될 수 있다.- 여기에 있는 메모리 정보들로 프로세스에 메모리 누수가 발생했는지 알 수 있다.
S
: 프로세스의 상태를 나타낸다. CPU 를 사용하고 있는 중인지, I/O 를 기다리고 있는지, 아니면 아무 작업도 하지 않는 유휴 상태인지 나타낸다.
- 프로세스의 상태는 다음과 같다.
S
: sleeping. S 는 D 와 유사하지만 시그널을 주면 언제든지 실행할 수 있다.D
: Uninterruptible sleep. 디스크 혹은 네트워크 I/O 가 걸려있는 상태를 말한다.R
: running. 실행 중인 프로세스로 실제로 CPU 를 먹고 있는 상태다.T
: traced or stopped. trace 등으로 프로세스의 시스템 콜을 추적하고 있는 상태다.Z
: zombie. 좀비 프로세스로 부모 프로세스에 의해서 회수되지 못한 자식 프로세스가 남겨져 있는 상태다. 좀비 프로세스의 문제는 적은 리소스를 메모리에서 계속 가지고 있는 문제와 PID 를 점유하고 있는 문제가 있다.****
malloc() 과 같은 메모리 할당을 호출하는 시스템 콜을 필요로 하는 함수를 호출한다면 RES 가 높아질 것이라고 생각하지만 그렇지 않다. VIRT 만 올라간다.
실제로 메모리에 쓰기 작업이 일어나는 시점에 메모리가 할당되고 RES 가 올라갈 것이다.
가상의 메모리만 처음에 할당 받고 실제로 쓰기 작업을 했을 때 Page Fault 가 일어난다. 그리고 그제서야 메모리를 할당한다. 이 일련의 과정을 Memory Commit 이라고 한다.
- 이런 정보는 커널 내의 전역변수인 Page Table 에서 모두 관리한다.
Memory Commit 이 필요한 이유는 COW (Copy-On-Write) 라는 기법을 위해서 필요하다.
그리고 VIRT 도 한도 끝도 없이 올라가는게 아니라 실제 물리 메모리와 관련이 있다. 실제로 사용하고 있는 물리 메모리가 없다면 Swap 을 사용하게 되거나 OOM 으로 프로세스를 죽이는 방법으로 메모리를 확보하게 된다.