꿈소년의 개발 이야기

OOM 및 LMK 에 대한 정리 본문

Android Development

OOM 및 LMK 에 대한 정리

꿈소년 2012. 8. 21. 09:05
반응형

아래 내용 및 참고 자료는 아래 주소에서 인용 및 참조하였습니다.

http://shadowxx.egloos.com/10781292


* OOM 이란 ?

Out Of Memory 의 약자. 컴퓨터 시스템에서 어떤 동작 수행을 함에 있어서 필요한 메모리가 부족하거나 없는 상태.

http://en.wikipedia.org/wiki/Out_of_memory


* LMK 란?

Low Memory Killer 의 약자. 안드로이드 시스템에 최적화한 OOM 관리 모듈.


이하 내용은 http://shadowxx.egloos.com/10781292 에 인용 및 참조함.


Android memory management

0. OOM Killer
- linux kernel의 메모리 부족시 메모리 확보를 하는 process
- src 위치 : mm/oom_kill.c

- 기본 설명 :
시스템 구동중 메모리가 부족하면 운영체제 내부의 우선순위 알고리즘에 의해 프로세스를 죽인다.
리눅스 커널은 프로세스의 메모리 할당시 남은 메모리가 없는 상황을 처리하기 위해 OOM(Out of Memory) Killer 를 가지고 있다.
그 것은 모든 프로세스를 어떤 제약으로 점수를 매겨 init을 제외한 최고 점수의 프로세스는 죽여 메모리를 확보한다.
따라서 일반적으로 서버를 운영할때에는 서비스데몬이 oom-killer에게 안죽도록 메모리관리를 잘해야한다

- Wiki OOM
most cases, a computer with virtual memory support where the majority of the loaded data resides on the hard disk would probably run so slowly due to excessive paging that it would be considered to have failed,
prompting the user to close some programs or reboot. As such, an out of memory message is rarely encountered by applications with modern computers
The typical OOM case in modern computers happens when the operating system is unable to create any more virtual memory, because all of its potential backing devices have been filled.
Operating systems such as Linux will attempt to recover from this type of OOM condition by terminating a low-priority process, a mechanism known as the OOM Killer

- OOM 발생 원인
커널은 Virtual memory를 이용한 메모리 할당을 하므로 실제 가용한 physical 메모리 보다 큰 프로그램 size의 메모리를 할당 할 수 있다.
즉 프로그램에서 당장 사용하지 않는 메모리는 나중에 메모리를 할당하기 때문에 실제 사용 가능한 메모리를 넘는 process도 load될 수 있다.(이것을 overcommit 이라 한다.)
만약 overcommit된 메모리에 실제 뭔가 쓰여지기 시작하면 메모리가 모자라므로 Out of memory가 발생한다.

- OOM Killer Configure
/proc/meminfo/CommitLimit : Commit Limit / SWAP + SOME REAL MEMORY
/proc/meminfo/Committed_AS : 현재 Commited 된 양
/proc/sys/vm/overcommit_memory : (mode 0 - heuristic / mode 1 - always overcommit / mode 2 - strict overcommit, overcommit 불가)
/proc/sys/vm/overcommit_ratio : The percentage can be more than 100, for a situation where you have lots of programs that don't use much of their allocated space.(percentage of real memory)

- Kill Policy
* The formula used is relatively simple and documented inline in the
* function. The main rationale is that we want to select a good task
* to kill when we run out of memory.
*
* Good in this context means that:
* 1) we lose the minimum amount of work done
* 2) we recover a large amount of memory
* 3) we don't kill anything innocent of eating tons of memory
* 4) we want to kill the minimum amount of processes (one)
* 5) we try to kill the process the user expects us to kill, this
* algorithm has been meticulously tuned to meet the principle
* of least surprise ... (be careful when you change it)

- Comment
기본적으로 OOM은 적은 수의 프로세스를 죽여서 많은 양의 메모리를 확보할 수 있는 heuristic을 쓰는 것을 알 수 있다.
OOM killer가 heuristic에 기반하고 있기 때문에, 중요한 server process가 죽지않는 다는 보장을 하기가 힘들다
하지만, OOM killer를 쓰지 않는다고 하더라도, 특정 프로세스가 종료할 때까지 기다리는 수 밖에 없고,
page fault handler에서 page frame을 할당받지 못하면, init를 제외한 해당 task는 kill 되기 때문에, OOM 상황에서는 어차피 치명적인 상황이 발생한다.
따라서, OOM 상황이 발생하지 않도록 노력하는 것이 중요하여 이때문에 안드로이드에서는 별도로 LMK를 사용하고 있다.

- Reference site
* http://blog.naver.com/PostView.nhn?blogId=pinocc&logNo=120059187934
* http://blog.naver.com/newbeing2000/30036826720
* http://lechuck.tistory.com/38
* http://andstudy.springnote.com/pages/3667993

 

1. Low Memory Killer
- 안드로이드에 특화된 OOM
- src위치 : /drivers/staging/android/lowmemorykiller.c(공식 커널에선 제외되어 안드로이드 커널에서만 볼 수 있다.)

- 기본설명
low memory killer는 구글 직원이 2009년에 안드로이드 메모리 관리를 위해 작성한 리눅스 커널 모듈이다
이 커널이 등장한 배경은 리눅스 메모리 정책이 현재 임베디드 환경에 맞지 않다는 것이다.
리눅스 커널의 기본 메모리 정책은 OOM Killer로 대표되는데 메모리가 부족한 상황에서 최대한의 가용성을 확보하기 위해 가상 메모리를 가장 많이 할당한 프로세스를 죽이는 형태로 되어 있다.
이런 정책은 서버나 임베디드 환경에서 주요 서비스나 주요 어플리케이션을 죽일 수 있다.
안드로이드의 가용 RAM이 설정된 Threshold 이하로 떨어지게 되면 프로세스 중요성별로 분류된 6가지 그룹중 해당 Application을 Kill 하도록 설정되어 있습니다.
그래서 시스템을 최종 사용자(end user) 관점에서 안정적이게 만든다.

-Application을 6가지 타입으로 분류

- LMK Configure
# cat /sys/module/lowmemorykiller/parameters/adj
cat /sys/module/lowmemorykiller/parameters/adj
0,1,2,4,7,15
# cat /sys/module/lowmemorykiller/parameters/minfree
2048,3072,4096,6144,7168,8192
위 값은 4KB 페이지 단위로 표현된 것을 보여준 것이고, 4번째 값인 7168이 HIDDNE_APP 의 Threshold에 해당.
가용 RAM이 7168 * 4K = 29M로 줄어들어야 HIDDEN_APP을 Kill 하도록 설정되어 있음
이 값은 /init.rc에 표기되어 있음


- Kill Policy
1. 어플리케이션은 자신의 상태(adj)를 항상 가지고 있는다. (/proc/<pid>/oom_adj)
2. 운영체제는 몇개의 메모리 문턱(minfree)을 가지고 있어서 단계로 메모리 문제를 다룬다.
3. 운영체제는 어플리케이션의 상태 변화를 인지하여 어플리케이션 상태를 수정한다.
4. adj과 minfree 값은 짝을 이룬다. (0, 1024) (8, 4096)
5. minfree값 이하로 메모리가 남은 경우 adj 값 이상의 어플리케이션을 제거한다. (4096 페이지 이하일 경우 adj 값 8 이상의 어플리케이션 중 하나가 제거된다.)
6. adj 값이 높을 수록 먼저 제거되고 차순으로는 가상 메모리 양을 비교한다. (4096 페이지 이하일 때 8과 10이 있을 경우 10이먼저 제거된다.)
*3번 과정인 어플리케이션 상태 수정은 유저 레벨 서비스인 ActivityManager가 변경한다.
어플리케이션 상태는 GUI와 깊은 연관이 있기 때문에 커널 레벨에서 일방적으로 결정하기에는 부적절하다

- Reference
http://barriosstory.blogspot.com/2009/02/taming-oom-killer.html
http://s2junn.tistory.com/45
http://dalinaum-kr.tumblr.com/post/4528344482/android-low-memory-killer