안드로이드, OutOfMemoryError : bitmap size exceeds VM budget 해결해보자!! |
OutOfMemoryError: bitmap size exceeds VM budget 해결방법 #1
메니페스트의 applicaation tag 에 android:largeHeap="true" 를 준다.
이 경우 원래보다 더 큰 용량의 힙 사이즈를 사용할 수는 있지만,
GC 시간이 더 오래 걸리는 등의 문제가 생기기 쉽다.
게다가 정확한 heap increase 가 보장되지 않는다.
결국 완벽한 solution 은 되지 못하고, 아주 특수한 상황에 한번씩 엄청난 양의 heap size 가
필요할 때만 쓸 수 있는 미봉책정도가 되겠다.
OutOfMemoryError: bitmap size exceeds VM budget 결방법 #2
메모리를 트레이스를 하여 원인을 제거해보자.
> adb shell dumpsys meminfo <packageName>
위 명령어를 이용하여 메모리를 보자.
** MEMINFO in pid 10141 [com.tes.test] **
Shared Private Heap Heap Heap
Pss Dirty Dirty Size Alloc Free
------ ------ ------ ------ ------ ------
Native 16 60 16 9704 8862 481
Dalvik 11010 14152 10784 23879 18308 5571
Cursor 0 0 0
Ashmem 0 0 0
Other dev 10812 60 10808
.so mmap 2233 3800 1484
.jar mmap 0 0 0
.apk mmap 114 0 0
.ttf mmap 111 0 0
.dex mmap 1148 0 0
Other mmap 6325 112 164
Unknown 4746 292 4744
TOTAL 36515 18476 28000 33583 27170 6052
Objects
Views: 324 ViewRootImpl: 13
AppContexts: 2 Activities: 1
Assets: 3 AssetManagers: 3
Local Binders: 6 Proxy Binders: 17
Death Recipients: 0
OpenSSL Sockets: 0
SQL
MEMORY_USED: 0
PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
Asset Allocations
zip:/data/app/com.tes.test.apk:/resources.arsc: 237K
여기서 우리가 주의해서 봐야 할 것은 PSS.
어떤 operation 을 하고, DBMS 에서 gc 를 돌렸을 때 메모리가 계속 늘어나선 안 된다.
즉 어떤 operation 을 하고 gc 를 하면 해당 메모리가 반환되어야 한다는 소리.
OutOfMemoryError: bitmap size exceeds VM budget 해결 방법#3
System.gc() 를 강제호출해준다.
gc 가 동작하는 로직에 대한 확신이 없거나,
특수한 경우에 gc 를 하고 operation 을 수행해야 할 정도로 메모리를 크게 먹는 경우에는
System.gc() 를 한번 호출해주는 것도 "괜찮을 수" 있다.
하지만 System.gc() 에 대한 호출은 고급 프로그래머들이 다 비추한다.
잘못된 gc 호출은 performance 이슈를 일으킨다.
즉, VM 이 알아서 gc 를 하도록 유도하는 것이 좋은 프로그래밍이다.
OutOfMemoryError: bitmap size exceeds VM budget 해결 방법#4
메모리 chasing 을 하는데 DDMS 의 Dump Heap 을 이용한다.
작은 아이콘 중 [Dump HPROF file] 을 클릭하여 메모리 상황을 파일로 export 시킨다.
그리고 MAT ( Eclipse Memory Analyzer ) 를 이용하여 이를 분석해본다.
이 DUMP 된 파일은 바로 열수 없고 아래 명령어를 통해서
hprof-conv <dumpFile> <newDumpFile>
conversion 을 시켜준 후에, MAT 으로 열 수 있다.
여기서 봐야 할 것은 "retained size".
여기서 retained size 가 큰 object 가 많이 있다면 문제가 된다.
요 녀석이 leak 이 될 확률이 높다.
OutOfMemoryError: bitmap size exceeds VM budget 해결 방법#5
마찬가지로 DDMS 에서 [Update Heap] 과 [Heap] 태그를 이용해서 memory tracking을..
[Allocation Tracker] 도 사용하면 좋다.
OutOfMemoryError: bitmap size exceeds VM budget 해결 방법#6
Activity 나 Fragment, 또는 View 가 사라질 때 강제로 view의 drawable 에 대한
callback 을 해제해주고, child 를 제거해주자.
@Override
protected void onDestroy() {
super.onDestroy();
unbindDrawables(findViewById(R.id.RootView));
System.gc();
}
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup && !(view instanceof AdapterView) ) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
이 때 AdapterView 의 경우 removeView 계통을 UnsupportedOperationException 으로
처리하기 때문에 이에 대한 검사가 필요하다.
'프로그래밍 놀이터 > 안드로이드, Java' 카테고리의 다른 글
[Java] Reflection Tutorial - Accessing Private Field, Private Method (0) | 2013.12.17 |
---|---|
[android] 런타임에 다른 apk 소스 ( dex 파일 ) 읽어오기. (0) | 2013.12.16 |
[android] ListView HeaderView ListItem 으로서 click 안 되도록 하기. (0) | 2013.12.11 |
[android] volley library 에 대해 알아보자! (0) | 2013.12.10 |
[java]DatagramSocket bind() connect() difference (0) | 2013.12.10 |
댓글