2013년 8월 16일 금요일

Android상에서 Bitmap 처리 관련 링크들 및 Out Of Memory에 대한 개인적인 방안

이전 블로그에서 이전 함 (원본 글 2013/08/16 작성)

Android 상에서 bitmap 처리 관련해서 정리

아래 링크만 참고하세요..
[Android 앱 메모리 최적화]
: (추가) Naver 개발자가 작성한 내용으로 안드로이드 메모리 관련해서 총정리 되어 있습니다.
http://helloworld.naver.com/helloworld/539525

아님 그냥 image loading library 쓰세요..




자바라고 GC 밑고 생각 없이 짜다간 정말 고생할듯....
아니.. 지금 OOM때문에 고생 중이다. 안드로이드 개발 시 ImageView 사용하면
무조건 맞닥드릴 문제인것 같다. 근데 좀 이상한건 관련 패턴 같은게 없다.
사실 나도 지금 정리중이지만 해결이 안되는 leak들이 있음.

일단 개인적인 방안으로는 

- Bitmap을 관리하는 class를 만들어 생성 한 뒤 caching하여 사용하고 메모리 부족 시 스케줄링 방법에 따라서 bitmap recycle을 하는 방법을 사용함.

- 각 activity, fragment에서는 onDestory(), onDetach()에서는 기분째즈님의 "안드로이드 메모리 누수 줄이기"에서 소개한 recursive하게 rootview의 widget을 모두 초기화 함.
 : 하지만 재미 있는 것은 rootview의 widget들을 null 초기화 하고 adapter의 view의 bitmap도 null 초기화 하지만 bitmap reference가 살아 있는게 보인다. 일단 위의 방법을 사용해서 bitmap을 강제로 recycle하므로 문제는 없을 듯.

- context, UI 관련된 widget 참조를 WeakReference를 사용하여 참조하게 함.


[Displaying Bitmaps Efficiently]
: Bitmap 관련된 기본적인 작업들에 대해서 설명.. 뭐 기본이겠다..

[ImageView Bitmap 처리 관련 게시물]

[Bitmap과 힙메모리에 대한 소고..]
: EastGem님이 여러모로 실험을 해서 나온 결과를 정리해 놓았음.

실험 1에서  EastGem님께서 아래와 같은 내용을 말해주고 있었음.
 실험1.
자 요렇게 자료형태를 구성했다.

1. Main 에서 View1, View2 로 참조시켜도 둘다 표현이 된다.
2. 셋중 어느 한군데서 recycle() 을 호출하면 모두 표현불가능해진다. ( invalidtate() 를 호출하기 전에는 표시되어있던건 그냥 있다 )
3. View 로 참조후 Main 에서 bitmap = null 을 줘도 View에서 사용하는데 아무 지장이 없다.
4. View 에서 참조후 한군데서 null 을 줘도 다른 View 나 메인에서는 아무 이상이 없다. 다른 View 로 다시 참조도 가능하다.
5. 두개의 이미지를 번갈아 수십 수백번 하나의 bitmap 참조에 할당해도 문제가 없다.

결론.
Bitmap 클래스는 비트맵의 메모리상의 위치와 크기, 밀도, 등의 각종 정모만 가질뿐.. 실제 Bitmap 의 내용을 변수로 갖지 않는다. 메모리상에서 참조해야할 위치만 가지고 있다고 생각된다. recycle 을 하면 메모리는 해제되지만 getWidth(), getDensity() 같은걸 해보면 정보는 다 그대로 가지고 있다. 메모리를 해제해도 invalidate()를 호출하기 전에 화면이 그대로 있으니 비디오 장치는 따로있다는 말이렸다.
메인에서는 View 로 생성한 Bitmap 을 넘긴후 즉시 null 처리해 버려도 전혀 문제가 되지 않는다.

=> 그래서 일단 App에서 사용하는 Bitmap들은 한곳을 통해 생성하고 관리해도 좋을 것 같다는 생각이 들어 아래와 같은 class 생성
 - Bitmap을 생성해주고 이를 cache하여 같은 resource(bitmap)을 요구할 경우 기존 생성된 cache를 전달
 - Bitmap 생성 시 OOM이 발생할 경우 cache를 스케줄링 방식에 따라 recycle.

 그래서 상위 class를 통해서 모든 bitmap을 생성 및 관리하고 생성된 bitmap을 참고하는 view에서는 단지 null 만 함..


[안드로이드 메모리 누수 줄이기]
: viewgroup의 widget들을 null 처리하거나 adapter에서 메모리 해제를 위한 방법 제공

Root view의 모든 widget들을 recursive하게 참조를 제거해 주는 방법은 괜찮다. 일단 각 activity에서 destory될 때 해당 함수 호출 하여 view와 관련된 resource를 제거 하게 함.


[Android 개발가이드 - Bitmap.recycle()은 가급적 호출해 주는 편이 좋다. (Android 2.x 버전)]
[출처] 아래 링크, 작성자 코드멍키
: 좀 이전 버전인데 맞는지는 모르겠다. 2013년 1월에 업데이트 되어 있는 comment에 의하면 단지 bitmap = null 로도 자원 반환이 가능하다는 의견.

[Points to consider for recycling Bitmap of ImageView] 

bitmap을 제거하는 방법은 recycle() & null 대입을 통한 reference 제거....

[Bitmap OutOfMemoryError]
: Bitmap OutOfMemoryError를 피하기 위한 방법들 소개

[bitmap decode한 결과물 recycle 하는 방법]
: decode한 이후 createBitmap의 결과가 같을 수도 있어 recycle을 하지 않아야할 경우가 있어 hashcode를 비교 필요.

[ImageView의 bitmap recycle]
: 헐.. 이렇게 해도 문제 없나? view가 완전히 destory 되지 않는 경우 "cannot draw recycled bitmaps" exception 발생 가능

댓글 없음:

댓글 쓰기