Overview of Android Memory Management ( 안드로이드의 메모리 관리 ) |
https://developer.android.com/topic/performance/memory-overview.html
-
Android Runtime ( ART ) 과 Dalvik 은 paging 과 memory-mapping 을 이용해서 메모리 관리를 한다.
app 이 조작하는 메모리는 모두 RAM 에 상주하며 page-out 되지 않는다.
이 memory 를 해지하는 방법은 GC 되도록 하는 방법밖에 없다.
수정이 발생하지 않는 code 와 같은 녀석들은 RAM 에서 page out 될 수 있다.
Garbage collection
-
Android 의 memory heap 은 세대가 있다(?).
예를 들어 최근에 allocate 된 object 는 젊은 세대(young generation) 영역에 할당된다.
그리고 이 녀석들이 오래 살아남으면 나이 먹은 세대(older generation) 영역으로 승격된다.
최종적으로는 영구 세대(permanent generation)이다.
각각의 heap generation 은 memory 양의 upper limit 이 있다.
한 generation 이 꽉 차면, system 은 gc 를 수행시켜 memory 를 정리한다.
gc 의 시간은 어떤 generation 을 청소하느냐와, 얼마나 많은 active object 가 있느냐에 따라 성능 차이를 보이게 된다.
-
GC 가 꽤 빨라지긴 했지만 그래도 app 성능에 영향을 준다.
GC 수행에 대한 조건들을 system 이 가지고 있고, 이 조건이 충족되면 해당 process 를 멈추고 gc 를 수행한다.
animation 도중이나 음악 재생 도중과 같은 어떤 과정의 중간에 수행될 수도 있는데, 이럴 경우 오래 걸릴 수 있다.
가끔 이렇게 오래 걸리는 경우에는 코드 실행을 16ms 이상 늦출 수 있으며, 그렇게 되면 UI 가 부드럽지 않게 된다.
Sharing Memory
-
Android 는 RAM page 를 process 간 공유하기도 한다.
각각의 process 는 Zygote process 로부터 fork 된다. Zygote 는 booting 시간에 시작해서 framework code 와 resource( 예를 들면 activity theme ) 들을 불러온다. 새로운 app process 를 시작할 때 system 은 Zygote process 를 fork 한 새로운 process 에서 app code 를 수행한다. 이 접근법으로 보았을 때 framework code, resource 는 모든 app process 에 share 된다.
가장 정적인 data 는 process 에 mmapped (memory-mapped) 된 것들이다. 이 데이터들은 process 간 share 될 수 있다. 그리고 page-out 될 수도 있다. 정적 data 의 예는 Dalvik code ( direct mmaping 을 위해 pre-linked 된 .odex 파일을 만듬으로써 ), app resource( resource table 을 구조화시켜서 ), 그리고 .so 와 같은 native code 이다.
많은 경우에 android 는 shared memory 영역을 명시적으로 할당해서 share 할 수 있게 만든다. ( ashmem, gralloc ). Window surface 는 app 과 screen compositor 간에 shared memory 를 사용한다. 그리고 cursor buffer 도 content provider 와 client 간에 shared memory 를 사용한다.
Allocating and Reclaming App Memory
-
Dalvik heap 은 각 app process 마다 하나의 virtual memory range 를 할당한다. 이 logical heap 크기는 system 한계까지 확장될 수 있다.
-
Logical heap size 는 실제 사용하는 heap 량과는 다른 개념이다.
Heap 을 자세히 보면. android 는 PSS (Proportional Set Size) 라는 단위를 사용해서 계산한다. 이는 다른 process 들과 share 하는 dirty, clean page 모두를 포함한다. system 은 이 PSS total 을 물리적 memory footprint 로 간주한다.
이에 관련해서 자세히 알고 싶다면 아래 링크를 보자.
https://developer.android.com/studio/profile/investigate-ram.html
-
Dalvik heap 은 heap 을 defragment 하지 않는다. Android 는 오직 heap 의 마지막 부분에 공간이 있을 때만 logical heap size 를 줄일 수 있다.
( ART 에서는 앱이 background state 일 때 heap compaction (또는 heap defragment) 를 수행한다.
https://source.android.com/devices/tech/dalvik/gc-debug )
Restricting App Memory
-
Multi-tasking 환경을 유지하기 위해서 android 는 각 app 에 heap size 를 엄격히 규제하고 있다. app 이 그 경계를 넘게 되면 OutOfMemoryError 가 발생한다.
-
System 에 얼마나 많은 메모리를 사용할 수 있는지 query 하고 싶어하는데, 이는 getMemoryClass() 를 사용함으로써 이룰 수 있다.
Switching apps
-
App switch 시 LRU(Least-Recently-Used) 기준으로 background 앱을 관리한다.
앱의 cached process 가 있고, 현재는 사용하지 않는 메모리를 가질 경우 system 의 전체 performance 에 영향을 미칠 수 있다.
System 이 low memory 가 되면 LRU 기준으로 process 를 kill 한다.
( 물론 이 때 오직 LRU 기준은 아니고 얼마나 memory 를 사용하는가도 고려한다. )
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[Android] ART vs. Dalvik (0) | 2018.10.11 |
---|---|
[Android] ART 의 GC 이야기 (0) | 2018.10.10 |
[android] Background Optimization ( 백그라운드 최적화 ) (0) | 2018.10.08 |
[android] Gradle Tutorial #2 (0) | 2018.10.05 |
[android] Gradle Tutorial #1 (0) | 2018.10.04 |
댓글