Search

'메모리'에 해당되는 글 2건

  1. 2011.06.11 어댑터 안에서 메모리 관리하기. (4)
  2. 2011.05.16 안드로이드 메모리 누수 줄이기 (36)

어댑터 안에서 메모리 관리하기.

Android 2011.06.11 21:56 Posted by 기분째즈

얼마 전에 내 블로그에 안드로이드 메모리 누수 줄이기 포스팅을 했는데, 어댑터 뷰에서 관리하는 법을 예제와 곁들어 추가로 설명할까 합니다.

어댑터뷰 안에 데이터는 실질적으로 어댑터가 관리를 하기 되기에 메모리 관리하는 부분도 어댑터 안에서 관리하는 게 좀 더 수월합니다. 가비지 콜렉터가 어느정도 알아서 관리를 해주나, 이미지처럼 메모리를 많이 사용할 경우 빠르게 해제하기 위해 직접관리를 해야하는 경우도 생깁니다.

다음 동영상은 저번에 올렸던 한 장씩 넘어가는 갤러리뷰에다가 고용량의 이미지 파일을 넣어서 메모리 관리가 되고 있는 모습입니다. (예를 들기 위해 오버했습니다. 실제로는 당연히 모바일 환경에 맞게 이미지를 줄여서 써야겠죠. 이미지 읽어들이는 시간도 꽤 길어서 멈추는 느낌이 드는데 이거 해결하는 기법은 포스팅하겠습니다) 바탕화면급 고용량 이미지라 빠르게 3~4장 정도만 이미지를 읽어도 java.lang.OutOfMemoryError: bitmap size exceeds VM budget이 발생합니다. 동영상보면 빨간색과 주황색 로그가 올라가는데 그게 Error가 발생한 부분이고 동영상은 메모리를 해제해주고 계속 작동 시키는  모습을 볼 수 있습니다.



어댑터에서 구현한 부분은 다음 부분입니다.


    //액티비티에서 어댑터를 메모리에서 해제하기 위해쓰는 메소드.
    //어댑터를 사용하는 액티비티의 onDestroy에 넣어주면 된다
.

    public void recycle() {

RecycleUtils.recursiveRecycle(mRecycleList);

    }


    //만들었던 뷰 목록 중 반을 지우는 메소드 

    public void recycleHalf() {

int halfSize = mRecycleList.size() / 2;

List<WeakReference<View>> recycleHalfList = mRecycleList.subList(0,

halfSize);

RecycleUtils.recursiveRecycle(recycleHalfList);

for (int i = 0; i < halfSize; i++)

    mRecycleList.remove(0);

    }



여기 RecycleUtils.recursiveRecycle은 전에 올렸던 메모리 누수 관리하기를 참고해주세요.

RecycleUtils 소스보기


WeakReference로는 레퍼런스를 해도 가비지 콜렉터할 때 신경을 안쓰기 때문에 가비지콜렉팅 대상에 포함됩니다. 예를 들어 Reference가 아니라 그냥 List에 View를 포함했다면 어댑터에서 자동으로 메모리 해제를 안하기 때문에 쉽게 메모리 오류가 발생할 겁니다.

    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

ImageView i = new ImageView(mContext);


try {

    i.setImageResource(mResources.get(position));

} catch (OutOfMemoryError e) {

    if (mRecycleList.size() <= parent.getChildCount()) {

Log.e(this + "", "size:" + mRecycleList.size());

throw e;

    }

    Log.w(this + "", e.toString());

    recycleHalf();

    System.gc();

    return getView(position, convertView, parent);

}

i.setAdjustViewBounds(true);

i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.MATCH_PARENT));

mRecycleList.add(new WeakReference<View>(i));

return i;




 이미지를 읽다가 OutOfMemoryError 예외가 발생하면 전에 어댑터에서 사용했던 뷰의 반을 메모리에서 해제하고, 재귀로 getView를 호출합니다. 오류가 안 날때까지 반씩 줄이다가 어댑터뷰의 크기만큼 줄였는데도 메모리오류가 나면 그냥 오류던지고 종료시키도록 구현했는데, 이 부분은 상황에 맞게 처리해주시면 되겠죠. 이건 그냥 메모리를 관리하는 하나의 예제일 뿐입니다. OutOfMemoryError가 자주 난다면 try/catch로 잡는 것보다 mRecycleList의 크기를 비교해서 미리 해제해주는 등의 더 섬세하게 관리를 해주셔야 될겁니다.

갤러리는 가로스크롤 되고 안에 있는 내용이 세로스크롤 되는 뷰는 다음에 설명하도록 하겠습니다. 완전히 세로로 스크롤 되는 건 원하시면 그냥 리스트뷰 쓰시면 되겠습니다.

ImageAdapter 소스 전체보기


소스는 이미지 리소스만 다르고 전에 올렸던 안드로이드 아이폰처럼 한장씩 넘기를 갤러리와 동일해서 생략하겠습니다.
신고

안드로이드 메모리 누수 줄이기

Android 2011.05.16 23:33 Posted by 기분째즈
2.x에 해당하는 글로 4.0부터는 더 적합한 방법이 많으니 Deprecated

더보기


신고


 

티스토리 툴바