마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

Bitmap.createBitmap 사용시 out of memory

0 추천

조금 전에도 관련 내용으로 질문을 올렸었는데요, 이미지 리사이징

부분은 그냥 아예 없애버렸습니다.. 그치만 리사이징이 문제가 아니더군요,, 

그래서 정리해서 다시 질문을 드리겠습니다..

 

일단 제가 뭘 만들고 있냐면, 1280 x 1800 비트맵을 생성하여 캔버스로

비트맵에 문서 양식을 그리고 있습니다. 문서양식 내용이 1800픽셀을 넘어갈 경우

현재 비트맵을 이미지로 저장 시키고 바로 비트맵을 이미지 뷰에 뿌려줍니다.

그리고 새로운 1280 x 1800 비트맵을 다시 만들어 캔버스로 못 다 그린 문서양식을

그리고 있습니다. 

비트맵을 생성해서 캔버스로 그리는 부분은 보시다시피 반복문으로 문서양식내용을

다 그리기 전 까지는 무한 반복 합니다. 

문서양식을 다 그리고 나면 해당 작업 액티비티는 피니시 됩니다.. 

 

여기서 문제가 위에 적은 작업을 A작업이라 한다면 

어플에서 A작업을 5번 이상 시켰을때, 5번째 작업부터 Bitmap.createBitmap()

에서 out of memory가 나옵니다.. 무조건 5번째 부터 나오더군요..

 

인터넷 검색해보고 질문도 올려가며 찾아보니 원인은

비트맵이 해제되지 않고 그대로 남아있어 그런거 같아 비트맵에 null을 주기도 하고

system.gc() 도 해보고 recycle()을 호출해봤지만, null과 system.gc()는 효과가 없고

recycle()은  Canvas: trying to use a recycled bitmap android.graphics.Bitmap에러를

뱉어 냅니다.. 이미지뷰에서 비트맵을 참조하고 있어서 인것 같은데 

어떤 타이밍에 recycle()을 호출 해야 될지도 잘 모르겠네요.. 도와주세요..

 

A작업의 로직은 아래와 같습니다. 



액티비티 A {
  Bitmap bm = Bitmap.createBitmap();
  Canvas canvas = new Canvas(bm);

  while (true) {
    //캔버스로 문서양식 내용을 그림

    if (문서내용이 1800 픽셀을 초과함) {
      bm.compress(현재 비트맵 jpg 이미지 파일로 저장);
      
      ImageView imageView = new ImageView();
      imageView.setImageBitmap(bm);

      if (더이상 그릴 내용이 없음) { 
        break; 
      } else {
        //어플 기동후 A작업을 5번 이상 실행시켰을때 이부분에서 oom발생
        bm = Bitmap.createBitmap();
        canvas = new Canvas(bm);
      }
    }
  }
}

 

익명사용자 님이 2014년 10월 30일 질문

2개의 답변

0 추천
 
채택된 답변
위의 크기되는 비트맵작업을 여러번 하면 안드로이드는 OOM 무조건 뿜습니다.

가비지 컬렉터에 대해서 한번 찾아보시기 바랍니다.

참초주소가 null 이 되어 객체가 그 누구의 참조를 받지 않는다 하더라도

그 쓸모 없는 객체를 가비지컬렉터는 바로 메모리로 회수하지 않습니다.

가비지 컬렉터가 한번 돌면서 수거해갈 객체들을 마킹해놓고 내부적인 알고리즘에 따라 최적의 시점에

그게 언제될지 모르지만.. 메모리를 수거해갑니다.

즉 리사이클 처리를 해도 바로바로 메모리를 회수할 수 없습니다.

자바랑 C랑 여기서 성능차이가 나게 되죠..

그리고 1800픽셀이면 상당히 큰 이미지 비트맵인데 파일로 임시로 저장해놓고 외부 라이브러리(이미지로더, 피카소)

등으로 이미지뷰에 디스플레이하고 메모리관리는 라이브러리에게 위임하시기 바랍니다.

1800픽셀이나 되는 비트맵을 몇개나 들고 이미지뷰에 뿌려주는것 자체가 엄청난 리스크인것 같습니다.

피씨라면 문제가 안될듯..
갸아악 (21,260 포인트) 님이 2014년 10월 30일 답변
0 추천
아마 다른 폰으로 하면 다른 횟수에 oom이 뜰 거예요.

사이즈를 줄이거나, 파일로 저장할 수 있으면 그걸로 어떻게든 회피를 해보심이....
쎄미 (162,410 포인트) 님이 2014년 10월 30일 답변
...