Swappiness in Linux 2.6
Linux 2.6의 swap 경향은 mm/vmscan.c에 의하면 다음과 같이 정의된다.
swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;
이 때, mapped_ratio는 다음과 정의된다.
/* * The point of this algorithm is to decide when to start * reclaiming mapped memory instead of just pagecache. Work out * how much memory * is mapped. */ mapped_ratio = ((global_page_state(NR_FILE_MAPPED) + global_page_state(NR_ANON_PAGES)) * 100) / vm_total_pages;
즉, mapped_ratio는 전체 메모리 크기에 대한 애플리케이션이 사용하고 있는 메모리 크기의 비율이다.
distress는 다음과 같이 정의된다.
/* * `distress' is a measure of how much trouble we're having * reclaiming pages. 0 -> no problems. 100 -> great trouble. */ distress = 100 >> min(zone->prev_priority, priority);
include/linux/mmzone.h에 따르면, priority는 priority of VM scanning이며, (아마도 free page를 확보하기 위해) 한번에 zone별 page 리스트를 스캐닝 하는 페이지의 수를 얻는데 (queue_length >> priority) 사용되며, 디폴트 값은 12로 한번에 2^12 = 4096개의 페이지를 스캔하는 것을 의미한다. (아마 free page를 확보하지 못해,) priority가 올라갈 수록 (값이 낮아질수록) 많은 페이지를 스캔하게 된다. 2.6 VM을 제대로 공부하지 않아서 이 부분은 확신할 수는 없다.
어쨌든, priority가 디폴트 값인 12일 때, distress값은 100/2^12 = 0이다.
swappiness는 sysctl이나 /proc/sys/vm/swappiness를 통해 사용자가 설정할 수 있는 파라미터이며, 0-100 사이의 값을 갖는다. swappiness의 디폴트 값은 60이다.
/* * From 0 .. 100. Higher means more swappy. */ int vm_swappiness = 60;
이런 값들로부터 계산된 swap_tendency가 100이 넘으면, mapped memory를 inactive list로 옮기기 시작한다. 다시 말하면, swap을 시작하게 된다.
예를 들어, 2GB의 메모리를 가지고 있는데, 1.8GB의 메모리를 애플리케이션이 사용하고 있고, distress가 0인 상태라면, swap_tendency는 1.8GB * 100 / 2GB / 2 + 0 + 60 = 105가 되어, swap 되기 시작한다.
결국, swap_tendency를 산출하는 식에 따르면, swappiness가 디폴트 값 60인 상태에서는 80% 이상의 메모리를 사용하기 시작하면, swap하기 시작한다. 다음과 같은 방법으로 swappiness 값을 조정함으로써, 이러한 swap behavior를 조정할 수 있다.
sysctl -w vm.swappiness=30
또는,
echo 30 >/proc/sys/vm/swappiness