본문 바로가기
프로그래밍 놀이터/안드로이드, Java

[android] Low Memory Kill ( LMK )

by 돼지왕 왕돼지 2019. 1. 9.
반응형

[android] Low Memory Kill ( LMK )


https://developer.android.com/guide/components/activities/process-lifecycle.html

https://medium.com/google-developers/who-lives-and-who-dies-process-priorities-on-android-cb151f39044f

android lmk, application kill, bg thread, broadcastReceiver, cached process, callback instance, CONTENT_PROVIDER, empty process, EMPTY_APP, foreground process, foreground service, FOREGROUND_APP, HIDDEN_APP, importance priority, important hierarchy, input method service, interact, JobService, live wallpaper, lmk ram threshold, lmk simulation, lmk 메모리, low memory kill, lowmemorykiller, LRU, minfree, onCreate, OnDestroy, onpause, onreceive, onresume, onStart, process, process priority dependency, Ram, requestPermissions() + onRequestPermissionsResult(), SECONDARY_SERVER, Service, Service Process, startActivityForResult() + onActivityResult(), startForeground, StartService, threshold, user interact, visible activity, Visible process, VISIBLE_APP, [android] Low Memory Kill ( LMK )


-

OS Version 별로 제조사별로 바뀌기 쉬운 정책 때문인지..

속 시원하게 설명해주는 글을 찾지 못했다.

그래서 항상 헛갈리는 LMK (low memory kill) 에 대한 내용을 한 번 더 정리해보았다.



-

여러 글을 참조한 결과 importance priority 는 약간의 조정이 있었던 것 같다. 아주 옛날 옛적에 developer 사이트 보며 정리한 글 http://aroundck.tistory.com/97 과 현재 developer 사이트는 조건과 값 명시 등이 조금씩 변화되었다.


대표적인 것은 foreground service 인데.. 

이 녀석이 이전에는 "Foreground process" category 였는데, 지금은 "Visible process" category 에 명시되어 있다.


어떤 버전부터 이렇게 변했는지 정확히 알 수 없기 때문에, 적절한 고려가 필요하다.



-

Low Memory Kill 는 안드로이드의 가용 RAM 이 설정된 Threshold 이하로 떨어지게 되면 어떤 규칙에 의해 Application 을 Kill 하는 것을 이야기한다.



-

LMK 의 가용 RAM threshold 는 /sys/module/lowmemorykiller/parameters/minfree 에 기록되어 있다.

2046, 3072, 6144, 7168, 8192, 8192 와 같이 써 있다.


FOREGROUND_APP, VISIBLE_APP, SECONDARY_SERVER, HIDDEN_APP, CONTENT_PROVIDER, EMPTY_APP 조건에 해당하는 앱들이 위에 명시된 threshold 값보다 낮아지면 죽는다.


이 값들을 importance hierarchy 라고 한다.



-

FOREGROUND_APP ( foreground process )


    Activity 가 screen 의 top 에 올라와 있고, user 와 interact 할 수 있다. (onResume() 이 불린 상태)

    BroadcastReceiver 가 onReceive() 함수를 수행하는중

    Service 가 onCreate, onStart, onDestroy 중 하나를 타고 있는 상태



-

VISIBLE_APP ( visible process )


    Activity 가 screen 에 visible 하지만 interact 할 수 없는 상태 (onPause()가 불린 상태)

    Service 가 startForeground 를 통해 foreground service 로 승격된 상태

    live wallpaper, input method service 등 user 가 service 가 돌고 있음을 알 수 있는 foreground service 로 작동하는 service 를 가진 녀석


   Visible activity 가 kill 당하면 black screen 으로 변한다.






-

SECONDARY_SERVER ( service process )


    startService 를 통해 시작한 Service 를 가지고 있는 녀석. 단, 긴 시작(예를 들면 30분 이상)동안 작동하고 있는 녀석은 다음에 나올 cached process 정도로 떨어질 수 있다.



-

HIDDEN_APP ( cached process )


    process 는 살아있지만 현재 사용하고 있지 않은 앱들이다.

    제거 순서는 LRU 이다.



-

EMPTY_APP ( empty process )


    나중에 앱이 재실행 되었을 때 switch 를 빨리 하기 위해 process 껍데기만 살아있는 녀석



-

LMK 관련해서 가장 많이 하는 실수 중 하나는 BroadcastReceiver.onReceive 에서 Thread 실행을 하고 App 이 죽지 않기를 바라는 것.

System 에서는 onReceive 에서 return 하고 나면 해당 component 를 더 이상 필요없는 component 로 간주한다. ( 매우 낮은 우선순위 )


BG Thread 대신 JobService 를 쓰는 것을 추천한다.



-

process priority 는 process 간 dependency 가 있다.

에를 들어 foreground 상태인 app의 service 에 binding 되어 있다던지,

foreground 상태인 app의 content provider 를 사용중이라면, 사용하는 앱도 foreground 이다.



-

startActivityForResult() + onActivityResult() 또는 requestPermissions() + onRequestPermissionsResult() case 에서 visible process 는 죽을 수 있다. 이것들은 callback “instance” 를 가진 case 가 아니기 때문이다.



-

정확한 정보인지 약간 의구심이 있긴 하지만.. 안드로이드는 component 단위로 죽이는 것이 아니라 process 단위로 죽인다.

"Android only kills processes, not components.”



-

LMK 를 시뮬레이션 하는 방법 중 하나는 아래와 같은 명령어로 죽이는 것이다.

adb shell am force-stop <packageName> 

adb shell kill <PID>




반응형

댓글