검색 엔진의 방문이 늘어나고 있군...

Posted
Filed under 시스템
참조 원문 : Understanding free command in Linux/Unix
참조 원문 : Help! Linux ate my RAM!

  free 명령어의 출력 결과를 보면 버퍼와 캐시라는 것이 있습니다.
$ free
             total       used       free     shared    buffers     cached
Mem:       4042408    1463740    2578668          0     171752     693644
-/+ buffers/cache:     598344    3444064
Swap:      4190204          0    4190204
  대체 이 버퍼와 캐시가 무엇일까요? 그리고 두 번째 줄(-/+ buffers/cache)에 있는 값은 뭘까요? 먼저 첫 번째 줄부터 살펴보겠습니다.
  • 4042408 : 메모리(물리적인 RAM)의 총량.
  • 1463740 : 시스템에서 사용하고 있는 메모리(RAM)의 총량으로 버퍼와 캐시된 데이터의 크기까지 포함.
  • 2578668 : 남은 메모리의 총량.
  • 0 : 공유된 메모리. 이 칼럼은 더 이상 사용되지 않으며 향후에 사라질 예정.
  • 171752 : 응용 프로그램들에 의해 버퍼된 메모리의 총량.
  • 693644 : 향후를 위한 데이터 캐싱에 사용한 메모리의 총량.
  그렇다면 버퍼와 캐시의 차이가 대체 뭘까요? 버퍼는 응용 프로그램별로 존재하는 임시 데이터 저장 공간으로서 이 데이터는 다른 응용 프로그램이 사용하지 않습니다. 반면 캐시는 더 빠른 접근을 위해 자주 사용하는 데이터를 저장하는 메모리 공간입니다. 캐시는 여러 번 사용될 수 있지만 버퍼는 한 번만 사용합니다. 둘 모두 데이터 처리를 위한 임시 공간이라는 공통점이 있습니다.

  아래는 두 번째 줄에 있는 값의 의미입니다.
  • 598344 : 실제 사용 중인 메모리의 총량. 사용하고 있는 메모리의 총량에서 버퍼와 캐시에 사용하고 있는 양을 뺀 값. 1463740 - (171752 + 693644) = 598344.
  • 3444064 : 실제 남은 메모리의 총량. 메모리의 총량에서 실제 사용 중인 메모리의 총량(위의 값)을 뺀 값.
     4042408 - 598344 = 3444064
  리눅스는 사용하고 있지 않는 메모리를 빌려서 디스크 캐싱에 사용합니다. 만일 메모리의 여유 공간(첫 번째 줄의 세 번째 값)이 없는 상태에서 어떤 응용 프로그램이 메모리를 할당받으려고 하면 리눅스는 즉시 버퍼/캐시가 여유 부리며 빌린 공간을 빼서 그 응용 프로그램에게 할당해줍니다. 즉, 실제 여유 공간은 첫 번째 줄의 세 번째 값이 아니라 두 번째 줄의 두 번째 값입니다. 이에 대한 더 자세한 내용은 이곳을 참조하시기 바랍니다.


2013/07/15 22:20 2013/07/15 22:20
Posted
Filed under 시스템
참조 원문 : Linux Memory Management – Swapping, Caches and Shared VM

1. 리눅스 스왑핑(Swapping)
  프로세스가 가상 페이지를 물리 메모리에 올려야 하는데 물리 메모리에 여유 공간이 없으면 이미 물리 메모리에 있는 다른 페이지를 버려야 합니다. 만약 버릴 페이지가 실행 이미지나 데이터 파일에서 읽어들였으며 읽은 후 그 페이지에 쓰기를 하지 않았었다면 쉽게 버릴 수 있습니다. 왜냐면 필요할 때 같은 페이지를 같은 실행 이미지나 데이터 파일로부터 물리 메모리로 다시 옮겨오면 그만이기 때문입니다.

  하지만 그 페이지에 쓰기를 했었다면 문제가 복잡해집니다. 이런 페이지를 더티 페이지(dirty page)라고 부릅니다. 더티 페이지는 보존시켜서 나중에 다시 사용해야 합니다. 더티 페이지를 물리 메모리에서 버릴 때는 스왑 파일(swap file)이라는 특수 파일에 저장합니다. 바로 이것을 스왑핑(swapping)이라고 합니다.

  스왑 페이지에 접근하는데 걸리는 시간은 프로세서의 속도와 비교했을 때 엄청나게 느립니다. 그렇기에 OS는 좋은 스왑핑 알고리즘(버리느냐 스왑핑을 하느냐를 결정하는 알고리즘)을 가지고 있어야 합니다. 신통치 않은 스왑 알고리즘은 실제 처리는 안 하고 스와핑만 하며 시간을 잡아먹는 현상을 야기합니다. 이런 현상을 쓰래싱(thrashing)이라고 합니다.

  또한 어떤 프로세스가 계속해서 사용하는 일련의 페이지 세트를 워킹 세트(working set)라고 합니다. 좋은 스왑 알고리즘은 OS가 쓰래싱에 걸리는 것을 최소화해야 하며 모든 프로세스의 워킹 세트가 항상 물리 메모리에 있도록 만들어야 합니다.

  리눅스는 어떤 페이지가 메모리에 있어야 하는가와 어떤 페이지를 버려야 하는가를 결정하기 위해 '최근 최소 사용(Least recently used)' 스키마를 사용합니다.

  이 스키마에서는 물리 메모리에 있는 각 페이지가 나이 값을 가지고 있습니다. 나이는 페이지의 사용여부로 변합니다. 만약 페이지가 자주 사용된다면 나이가 매우 어릴 것이며, 사용되지 않으면 점점 늙게 됩니다. 더 늙은 페이지가 물리 메모리에서 스왑당하거나 버려집니다.


2. 캐쉬(Caches)
  캐쉬는 프로세서, OS, 그리고 그 둘 사이에서 벌어지는 처리를 더 빠르게 만들기 위한 개념입니다. 리눅스에서 중요한 캐쉬로는 아래와 같은 것들이 있습니다.

(1) 리눅스 스왑 캐쉬
  앞서 설명처럼 더티 페이지(물리 메모리에 올린 후로 내용이 변형된 페이지)만 스왑핑을 합니다. 또한 페이지가 변형되어 스왑된 후 다시 물리 메모리로 돌아온 상태에서 또 다시 스왑해야 할 때 페이지가 변한 게 없다면 스왑할 필요 없이 그냥 버리면 됩니다. 이렇게 해서 아낄 수 있는 시간이 꽤 됩니다. 이 개념을 실현하기 위해 리눅스에서는 스왑 캐쉬라는 것을 사용합니다.
  • 스왑 캐쉬는 물리 페이지 당 하나의 엔트리가 있는 페이지 테이블이다.
  • 각 엔트리는 스왑당한 하나의 페이지와 연관되어 있으며 스왑 파일에 대한 정보를 담고 있는데 그 정보란 스왑 파일 속 그 페이지의 정확한 위치다.
  • 스왑 캐쉬 안에 있는 페이지 테이블 엔트리 중 0이 아닌 게 있다면 그것은 스왑 파일 안에 있는 페이지를 뜻하며 그 페이지는 아직 변형되지 않았음을 뜻한다.
  • 어떤 페이지가 스왑 캐쉬 안에 자신의 엔트리를 가지고 있는 상태에서 변형됐다면 그 엔트리는 스왑 캐쉬에서 제거된다.
  • 이 방법으로 인해 캐쉬 안에는 마지막으로 스왑당한 뒤로 아직 변형되지 않은 페이지들만 남게 된다.
  이 방법을 통해 스왑 캐쉬는 스와핑 메커니즘의 효율성을 증대시킵니다.

(2) 하드웨어 캐쉬
  앞서 설명처럼 프로세서는 가상 주소를 물리 주소로 바꾸기 위해 페이지 테이블 엔트리를 읽습니다. 일반적으로 프로세서는 페이지 테이블 엔트리의 정보를 하드웨어 캐쉬에 저장합니다.

  이 하드웨어 캐쉬는 TLB(Translational look-aside buffer)들로 이뤄져 있습니다.

  프로세서는 가상 주소를 변환시킬 때마다 TLB로부터 페이지 테이블 엔트리 정보를 찾으려고 합니다. 만약 찾는데 성공하면 다음 일을 진행하지만 찾지 못한다면 OS에게 찾지 못했다는 사실을 알리며 문제를 해결하도록 지시합니다.

  OS에게 찾지 못했다는 정보를 전달할 때는 프로세서의 종류별로 다른 예외처리 메커니즘을 사용한다. OS가 알맞은 엔트리를 찾아 TLB 엔트리에 집어넣어 문제를 해결하면 프로세서는 TLB에서 그 엔트리를 다시 찾기 시작합니다.

(3) 리눅스 버퍼 캐쉬
  버퍼 캐쉬는 블록 디바이스 드라이버가 사용하는 데이터를 담고 있습니다.

  블록 디바이스 드라이버는 블록 단위로 데이터를 조작하는 것으로 고정된 크기의 데이터들이나 다수의 데이터 블록을 읽거나 쓸 수 있습니다. 버퍼 캐쉬는 여러 개가 존재하며 구분을 위해 디바이스 식별자(device identifier)를 사용합니다.

  버퍼 캐쉬는 읽기/쓰기를 매우 효율적이고 빠르게 해줍니다. 예를 들어 하드 디스크에 읽기/쓰기를 한다고 했을 때 그때마다 파일 I/O를 발생시키면 큰 시간을 낭비하게 되는데 버퍼 캐쉬는 그 사이에 위치하여 필요한 시기에 읽기/쓰기를 실시하고 남은 건 캐쉬에 쌓아 보관함으로서 시간을 절약하는 것입니다.

  스왑, 메모리, 페이지, 블록 IO, 트랩, 디스크, CPU 사용률은 vmstat이나 sar 같은 툴을 사용하여 볼 수 있습니다.


3. 공유 가상 메모리(Shared Virtual Memory)
  잘 작성한 코드에는 불필요하게 반복된 코드가 없습니다. 함수를 이용하면 같은 코드를 언제나 다시 부를 수 있죠. 자주 사용하는 함수들은 묶어서 라이브러리로 만듭니다. 공유 메모리도 이와 유사한데 뭔가를 메모리에 한 번만 올려놓고 여러 프로세스가 공용으로 사용하는 것입니다.

  가상 메모리는 프로세스가 메모리를 공유하기 쉽게 해주는데 왜냐하면 물리 주소는 페이지 테이블들을 통해 찾아간다는 점과 여러 프로세스의 페이지 테이블에서 같은 물리 페이지 프레임 번호를 쓸 수 있을 확률이 매우 높다는 점 때문입니다. 바로 이 개념이 공유 가상 메모리입니다.

2013/07/01 21:24 2013/07/01 21:24