티스토리 뷰

출처 : Linux Memory Management or 'Why is there no free RAM?'

2차출처 : http://halfpie.tistory.com/187


Revision 2.3
Copyright 2004 sapphirecat. The text of this post is licensed under a Creative Commons License.
의 내용을 번역한 것입니다.

항목

메모리 관리 Overview
x86 아키텍쳐에서의 불가사의한 880MB 제한
top 결과중 VIRT,RES,SHR 사이의 차이점
buffers 와 cache의 다른점
커널 2.6의 Swappiness
1. 메모리 관리 Overview
1. Overview of memory management

'top'같은 전통적인 유닉스 도구들은 종종 시스템이 잠깐동안 구동된 후 놀랄만큼 적은 양의 Free Memory를 보고하곤 한다. 예를 들어 약 3시간의 uptime후 내가 이 글을 쓰고 있는 머신은 512MB RAM를 가지고 있음에도, 60MB 이하의 free memory를 보고하고 있다. 모두 어디로 가버린걸까?
Traditional Unix tools like 'top' often report a surprisingly small amount of free memory after a system has been running for a while. For instance, after about 3 hours of uptime, the machine I'm writing this on reports under 60 MB of free memory, even though I have 512 MB of RAM on the system. Where does it all go?
사용된 것중 가장 많이 차지하는 것이 디스크 캐쉬이다. 현재 290MB를 넘고 있다. 이것은 top에서 "cached"로 나타난다. Cached 메모리는 실행중인(또는 새롭게 시작된) 프로그램이 메모리가 필요하다면 바로 대체될 수 있다는 점에서 본질적으로는 free memory이다.  
The biggest place it's being used is in the disk cache, which is currently over 290 MB. This is reported by top as “cached”. Cached memory is essentially free, in that it can be replaced quickly if a running (or newly starting) program needs the memory.
리눅스가 디스크 캐쉬에 그렇게 많은 메모리를 사용하는 이유는 그렇지 않으면 RAM이 낭비되기 때문이다. 캐쉬를 유지한다는 것은 만약 어떤 프로그램이 같은 데이타를 다시 필요로 할때 메모리에 해당 캐쉬가 존재할 가능성이 높다는 것을 의미한다. 메모리로 부터 정보를 Fetch하는 것이 하드 디스크로 부터 얻는 것보다 대략 1000배정도는 더 빠르다. 만약 캐쉬에서 찾지 못한다면, 어차피 하드 디스크에서 읽혀질 필요가 있다, but in that case nothing has been lost in time(^^; ? 그러나 그 경우는 과거에 한번도 읽혀진 적이 없다는 것이다)
The reason Linux uses so much memory for disk cache is because the RAM is wasted if it isn't used. Keeping the cache means that if something needs the same data again, there's a good chance it will still be in the cache in memory. Fetching the information from there is around 1,000 times quicker than getting it from the hard disk. If it's not found in the cache, the hard disk needs to be read anyway, but in that case nothing has been lost in time.

얼마나 많은 메모리가 어플리케이션이 사용 가능한 실제적인 여유공간인지에 대한 보다 정확한 판단을 위해 "free -m" 명령을 실행해 보아라.
To see a better estimation of how much memory is really free for applications to use, run the command: Code: free -m

-m 옵션은 메가바이트로 표시할 것을 가르킨다. 결과값은 아래와 같이 나타날 것이다.
The -m option stands for megabytes, and the output will look something like this: Code:

           total       used       free     shared    buffers     cached
Mem: 503 451 52 0 14 293
-/+ buffers/cache: 143 360
Swap: 1027 0 1027

-/+ buffers/cache 줄은 어플레케이션들 입장에서의 얼마나 많은 메모리가 사용되고 자유로운가를 보여준다. 일반적으로 만약 swap이 거의 사용되지 않는다면, 메모리 사용량은 성능에 전혀 영향을 주지 않는다.
The -/+ buffers/cache line shows how much memory is used and free from the perspective of the applications. Generally speaking, if little swap is being used, memory usage isn't impacting performance at all.

내 Machine에는 512MB의 메모리가 있다고 했었다. 그러나 free 명령에 의하면 503MB(역주 : total)가 이용가능하다고 되어 있다. 이는 주로 커널은 swapped 될 수 없기 때문으로 커널이 차지하는 메모리는 결코 free가 될 수 없다. 또한 그중에는 하드웨어에 의하거나 하드웨어를 위한 시스템 아키텍처와 밀접한 다른 목적의 메모리 영역도 있을 수 있다.
Notice that I have 512 MB of memory in my machine, but only 503 is listed as available by free. This is mainly because the kernel can't be swapped out, so the memory it occupies could never be freed. There may also be regions of memory reserved for/by the hardware for other purposes as well, depending on the system architecture.

2. x86 아키텍쳐에서의 불가사의한 880MB 제한
2. The mysterious 880 MB limit on x86

기본적으로, 리눅스 커널은 low 메모리에서만 실행되고 low 메모리만을 관리한다. 이는 page 테이블 관리를 조금은 더 쉽게한다, 이는 다시말해 좀더 빠른 메모리 엑세스가 가능하게 만든다. ^^; ???
By default, the Linux kernel runs in and manages only low memory. This makes managing the page tables slightly easier, which in turn makes memory accesses slightly faster. The downside is that it can't use all of the memory once the amount of total RAM reaches the neighborhood of 880 MB. This has historically not been a problem, especially for desktop machines.

1GB 또는 그이상의 머신에서 모든 RAM을 사용할 수 있기 위해서는 kernel을 제 컴파일 할 필요가 있다. 'make menuconfig'(또는 config가 제공되는 곳) 를 실행하고 다음의 옵션을 설정해야 한다.
Processor Type and Features --> High Memory Support --> (X) 4GB
To be able to use all the RAM on a 1GB machine or better, the kernel needs recompiled. Go into 'make menuconfig' (or whichever config is preferred) and set the following option: Code: Processor Type and Features —→ High Memory Support —→ (X) 4GB

이것은 커널 2.4와 2.6 둘다 적용되어 있다. High 메모리 지원을 활성화 하면 이론적으로는 약간의 엑세스 저하가 일어날수 있다. 그러나 Joseph_sys 와 log에 따르면, 실제적인 차이는 거의 없다.
This applies both to 2.4 and 2.6 kernels. Turning on high memory support theoretically slows down accesses slightly, but according to Joseph_sys and log, there is no practical difference.

3. top 결과중 VIRT,RES,SHR 사이의 차이점
3. The difference among VIRT, RES, and SHR in top output

VIRT는 프로세스의 가상 크기를 가르킨다. 이것은 해당 프로세스가 실제적으로 사용하는 메모리의 총량으로, 프로세스에 맵핑된 메모리(예로 X server를 위한 비디오 카드의 RAM), 프로세스에 맵핑된 디스크상의 파일들(대부분이 주로 공유 라이브러리들), 그리고 다른 프로세스들과 공유하는 메모리이다. VIRT는 프로그램이 현재 순간에 얼마나 많은 메모리에 접근할 수 있는지를 나타낸다.
VIRT stands for the virtual size of a process, which is the sum of memory it is actually using, memory it has mapped into itself (for instance the video card's RAM for the X server), files on disk that have been mapped into it (most notably shared libraries), and memory shared with other processes. VIRT represents how much memory the program is able to access at the present moment.

RES는 상주 크기를 나타낸다. 이는 프로세스가 소비하는 실제 물리적 메모리의 양이 얼마인지를 정확히 나타낸것이다.(이는 또한 바로 %MEM 컬럼과 일치한다.) 이는 대부분의 프로그램들이 C 라이브러리에 의존적이기 때문에 실제로 항상 VIRT 크기보다는 작을 것이다.
RES stands for the resident size, which is an accurate representation of how much actual physical memory a process is consuming. (This also corresponds directly to the %MEM column.) This will virtually always be less than the VIRT size, since most programs depend on the C library.

SHR은 VIRT 크기중 얼마만큼이 실제 공유가능한(메모리 또는 라이브러리들)가를 나타낸다. 라이브러리인 경우 이는 해당 라이브러리 전체가 상주한다를 것을 의미하지는 않는다. 예를 들어, 만약 한 프로그램이 한 라이브러리속의 일부 함수들만을 사용한다고 하면, 그것의 전체 라이브러리가 맵핑되고 VIRT와 SHR에 계수되겠지만, 사용되는 함수들을 포함하는 라이브러리 파일의 부분만이 실제적으로 로드되고 이는 RES로 잡힌다.
SHR indicates how much of the VIRT size is actually sharable (memory or libraries). In the case of libraries, it does not necessarily mean that the entire library is resident. For example, if a program only uses a few functions in a library, the whole library is mapped and will be counted in VIRT and SHR, but only the parts of the library file containing the functions being used will actually be loaded in and be counted under RES.

4. buffers 와 cache의 다른점
4. The difference between buffers and cache

버퍼는 특정한 블럭 디바이스와 관련되어 있으며, in-flight 페이지 트랙킹 뿐만아니라 파일시스템 메타데이터 캐싱을 포함한다. 캐쉬는 (^^;)parked 파일 데이타만을 포함한다. 즉 버퍼는 무슨 디렉토리이며 파일 권한은 어떻게 되고, 어떤 메모리가 특정 블럭 디바이스에 대해 쓰여지거나 읽혔는지를 유지하는 반면 캐쉬는 단지 파일의 내용 그 자체만을 포함한다는 것이다.
Buffers are associated with a specific block device, and cover caching of filesystem metadata as well as tracking in-flight pages. The cache only contains parked file data. That is, the buffers remember what's in directories, what file permissions are, and keep track of what memory is being written from or read to for a particular block device. The cache only contains the contents of the files themselves.

이 절의 내용에 대한 수정과 추가를 환영한다. 나는 이런 결론에 도달하기 위해 /proc/meminfo가 어떻게 생성되는지를 추적함으로서 추론을 완성할 수 있었다.
Corrections and additions to this section welcome; I've done a bit of guesswork based on tracing how /proc/meminfo is produced to arrive at these conclusions.

5. 커널 2.6의 Swappiness
5. Swappiness (2.6 kernels)

2.6 이후로 메모리가 가득 찯을때 캐쉬된것들을 디스크로 옮기는 스와핑이 얼마나 많이 이루어질지를 조율하는 방법이 생겼다.
Since 2.6,  there has been a way to tune how much Linux favors swapping out to disk compared to shrinking the caches when memory gets full.

ghoti의 추가분 : 어떤 어플리케이션이 메모리를 필요로하고 모든 RAM이 가득 찯다면, 커널은 일부 메모리를 free로 하기위한 두가지 방법을 갖는다. 가장 오래된 데이타를 제거함으로서 RAM에 있는 디스크 캐쉬를 줄이거나 또는 프로그램에서 거의 사용되지 않은 부분(pages)을 디스크의 swap 파티션으로 옮기는 것이다. 어떤 방법이 보다 효과적인지를 예측하는 것은 쉽지 않다. 커널은 활성도의 최근 이력에 근거하여, 주어진 순간에 두 방법의 적용정도를 대략적으로 측정함으로서 한가지를 선택한다.
ghoti adds: When an application needs memory and all the RAM is fully occupied, the kernel has two ways to free some memory at its disposal: it can either reduce the disk cache in the RAM by eliminating the oldest data or it may swap some less used portions (pages) of programs out to the swap partition on disk. It is not easy to predict which method would be more efficient. The kernel makes a choice by roughly guessing the effectiveness of the two methods at a given instant, based on the recent history of activity.

2.6 커널 이전에, 사용자가 계산에 영향을 주는 수단이 없어 커널이 종종 잘못된 선택을 하고 이로 인해 헛수고와 포퍼먼스 저하를 가져오는 상황이 있을 수 있었다. 커널 2.6에 swappiness의 추가로 이것이 변했다. ghoti에게 감사한다!
Before the 2.6 kernels, the user had no possible means to influence the calculations and there could happen situations where the kernel often made the wrong choice, leading to thrashing and slow performance. The addition of swappiness in 2.6 changes this. Thanks, ghoti!

Swappiness는 0에서 100까지의 값을 가지는데 스와핑과 캐쉬 free사이의 밸런스를 변화시킨다. 100이면 커널은 항상 비활성화된 페이지들을 찾아 디스크에 스왑할 것이다. 그밖의 경우, swapout(역주:비활성 페이지의 디스크 스왑)이 일어날지의 여부는 얼마나 많은 어플리케이션 메모리가 사용중이며, 캐싱하고 있는 발견중이고 제거중인 비활성화 아이템이 얼마나 적은가에 따른다.  
Swappiness takes a value between 0 and 100 to change the balance between swapping applications and freeing cache. At 100, the kernel will always prefer to find inactive pages and swap them out; in other cases, whether a swapout occurs depends on how much application memory is in use and how poorly the cache is doing at finding and releasing inactive items.

기본 swappiness값은 60이다. ???...(0값은 어플리케이션이 원하는 메모리를 캐시를 줄여 RAM의 단편으로 할 수 있도록하는 동작을 많이 하도록 하는것이다.???)  디스크의 spin down이 가능한 laptop의 경우 20또는 그 이하의 값을 추천한다.
The default swappiness is 60. A value of 0 gives something close to the old behavior where applications that wanted memory could shrink the cache to a tiny fraction of RAM. For laptops which would prefer to let their disk spin down, a value of 20 or less is recommended.

sysctl 에 따라, 다음 명령중 하나로 swappiness의 값을 실행중에 설정 가능하다.
# sysctl -w vm.swappiness=30
# echo 30 > /proc/sys/vm/swappiness
As a sysctl, the swappiness can be set at runtime with either of the following commands:
Code:
# sysctl -w vm.swappiness=30
# echo 30 >/proc/sys/vm/swappiness

시스템 시작시의 기본값은 /etc/sysctl.conf에 설정할 수 있다.
The default when Gentoo boots can also be set in /etc/sysctl.conf:
Code:
# Control how much the kernel should favor swapping out applications (0-100)
vm.swappiness = 30
어떤 패치들은 커널이 적당한 swappiness level를 자동으로 조절하는 것을 허락한다. 이는 사용자 값 설정을 유지하지 않을 수도 있다.
Some patchsets allow the kernel to auto-tune the swappiness level as it sees fit; they may not keep a user-set value.