정보공간_1

[2기 수원 이상웅] 리눅스 시스템 정보 알기 1 (/proc) 본문

IT 놀이터/Elite Member Tech & Talk

[2기 수원 이상웅] 리눅스 시스템 정보 알기 1 (/proc)

알 수 없는 사용자 2012. 9. 25. 22:00

개요

  /proc 파일 시스템은 메모리에 있는 시스템을 나타낸다. 그것의 목적은 커널 자원과 컴포넌트를 쉽게 보여주는데에 있으며, 현재 시스템에서 실행 중인 프로세스 정보도 확인 가능하다. 특히 따로 API를 호출하지 않고 시스템 정보를 가져와 읽기 쉬운 형태로 나타내어 주는 점이 특징이다. 덧붙여 proc의 항목들은 파일로 만들어져 있는데, 유저가 이 파일에 읽기로 접근 시, 디스크에 접근하여 정보를 가져오는 것이 아니라 즉석에서 만들어 제공하게 되어 있다.

 

프로세스 정보

  시스템에서 돌아가는 모든 프로세스는 /proc/process_id라는 디렉토리 형태로 정보를 나타낸다. 1 pid를 갖는 init의 경우 /proc/1/ 에 정보를 제공하고 있다. 그외에 제공하는 정보 항목은 다음과 같다.

항목

설명

auxv

ELF 보조 벡터.

cmdline

명령행 매개변수

cwd

현재 작업 디렉토리를 가리킴

environ

프로세스에 공개된 모든 환경 변수를 보여줌

exe

프로세스의 실행 파일을 가리킴

fd

프로세스가 열어놓은 모든 파일 목록

maps

실행 파일과 라이브러리에 대한 메모리 맵

mem

프로세스 메모리

mounts

마운트된 파일 시스템

root

프로세스 루트 디렉토리를 가리킴

stat

프로세스 상태를 읽을 수 있는 형태로 출력함

statm

프로세스 메모리 사용 정보

status

프로세스 상태

wchan

프로세스 대기 채널(wchan)에 대한 프로세스 선행 해석(predecode)

(출처 : 리눅스 디버깅과 성능 튜닝 / 박재호, 이해영 역)

  이중 특히 중요해서 볼 것은 statm인데, 본인이 개발한 프로세스의 메모리 사용량을 자세하게 알고 싶을 때에 중요하게 쓰인다. 다음은 init 프로세스의 statm 항목 정보이다.

 

  statm 7개의 값을 출력시키는데 그 의미는 다음과 같다.

1. 프로세스의 총 크기 (단위: 킬로바이트)

2. 메모리 영역 크기 (단위킬로바이트)

3. 공유 페이지 수

4. 코드 페이지 수

5. 데이터/스택 페이지 수

6. 라이브러리 페이지 수

7. 변경(dirty) 페이지 수

 

  즉 예제의 그림을 보면 프로그램의 총 크기는 6111kb이며 메모리 영역 크기는 587kb이다. 공유된 페이지수는 336, 코드 페이지 수는 38, 라이브러리 페이지수는 280개이며, 데이터/스택 페이지 수 및 변경 페이지수는 0개임을 알 수 있다. 이처럼 원하는 항목을 cat 명령어를 통해 보는 것이 proc 정보를 보는 일반적인 방법이다.


slabinfo

  slabinfo는 슬랩 메모리 사용에 대한 정보를 출력한다. 다음은 그 예제 화면이며, slab 에 대한 정보는 다음의 기사를 참고하기로 한다.


리눅스에서 사용하는 슬랩 할당자는 썬OS 운영체제를 위해 Jeff Bonwick이 처음으로 만든 알고리즘에 기반한다. Jeff가 만든 할당자는 객체 캐시를 중심으로 동작한다. 커널 내부에서 파일 기술자나 기타 공통 구조체를 위한 객체 집합을 위해 메모리를 미리 많이 할당해 놓는다. Jeff는 커널에서 정규 객체를 초기화하는 데 들어가는 시간이 할당과 해제에 필요한 시간을 초과한다는 사실을 발견했다. Jeff는 메모리를 전역 풀로 되돌려서 해제하는 대신 의도한 목적에 맞춰 초기화한 상태로 메모리를 유지해야 한다고 결론지었다. 예를 들어, 뮤텍스용 메모리를 할당했다면 뮤텍스 초기화 함수( mutex_init )는 뮤텍스를 위해 메모리를 처음 할당할 때 한번만 수행하면 된다. 연속적인 메모리 할당이 이런 초기화 작업을 수행하지 않아도 되는 이유는 직전에 호출된 할당 해제와 제거 함수를 통해 이미 초기화 상태로 바뀌었기 때문이다.

시간과 공간 모두를 효율적으로 만드는 메모리 할당자를 만들기 위해 리눅스 슬랩 할당자는 이런저런 아이디어를 활용했다.

그림 1은 슬랩 구조체를 상위 단계에서 보여준다. 최상위 단계에 cache_chain 이 있는데 슬랩 캐시를 연결 리스트로 묶는다. 이는 최적 적합 알고리즘에 유용한데, (목록을 순회하면서) 요구하는 할당 크기에 가장 근접한 캐시를 찾아주기 때문이다. cache_chain 의 각 구성 요소는 (캐시라고 부르는) kmem_cache 구조체 참조다. 이는 관리를 위해 크기가 정해진 객체를 담은 풀을 정의한다.


그림 1. 슬랩 할당자를 구성하는 주요 구조 
그림 1. 슬랩 할당자를 구성하는 주요 구조 

각 캐시는 슬랩 목록을 포함하는데 (일반적으로 페이지에 들어가는) 연속적인 메모리 블록이다. 슬랩 종류는 다음과 같은 세 가지다.

slabs_full
완전히 할당된 슬랩
slabs_partial
일부 할당된 슬랩
slabs_empty
비어있거나 객체를 할당하지 않은 슬랩

slabs_empty 리스트에 있는 슬랩은 주요 수확 대상이다. 슬랩이 사용한 메모리는 다른 목적을 위해 운영체제에 반환되는 과정을 거친다.

슬랩 리스트에 있는 각 슬랩은 연속적인 메모리 블록이며(하나 이상 연속된 페이지) 객체로 쪼개진다. 이런 객체는 특별한 캐시에서 할당되고 할당이 해제되는 기본 구성 요소다. 슬랩은 슬랩 할당자가 할당하는 최소 단위이므로 더 많은 공간이 필요하다면 슬랩 단위로 확장되어야 한다. 일반적으로 다양한 객체가 슬랩 단위로 할당된다.

객체가 슬랩에서 할당되고 할당이 해제될 때 개별 슬랩은 슬랩 리스트에서 이동할 수 있다. 예를 들어, 모든 객체가 슬랩 내부에서 사용되었을 경우 slabs_partial 리스트에서 slabs_full 리스트로 이동한다. 슬랩이 꽉차고 객체 할당이 해제될 때, slabs_full 리스트에서 slabs_partial 리스트로 이동한다. 모든 객체 할당이 해제될 때 slabs_partial 리스트에서 slabs_empty 리스트로 이동한다.

(출처 : https://www.ibm.com/developerworks/kr/library/l-linux-slab-allocator/)


그 외의 항목들에 대해서는 2편에서 이어하기로 하겠다.