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

[android] OutOfMemoryError : bitmap size exceeds VM budget 을 해결해보자!!!

by 돼지왕 왕돼지 2013. 12. 13.
반응형


 안드로이드, OutOfMemoryError : bitmap size exceeds VM budget

해결해보자!!

 


[android] 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 으로

처리하기 때문에 이에 대한 검사가 필요하다.






반응형

댓글