지금껏 GC의 힘을 믿고.. 자바에서 메모리 문제 신경쓴적 없는데..
으.. 이상한데서 발목 잡혀 버렸습니다.
이미지가 여러개 있으면 이전, 다음 버튼을 누를시에 ImageView에 이전그림 다음그림을 보여지는 간단한 내용입니다.
각각의 이미지는 byte[]로 되어있어 Bitmap 객체로 만들어 두었습니다.
액티비티간 이동이 또 있는데 intent는 용량제한이 있어 안되길레 클래스 하나 임시로 만들고 Bitmap 객체를 static 으로 두었구요..
결론적으로.. 이미지를 여러개 보다보면 어플이 죽습니다..
로그보니.. 메모리 누수 문제네요....;;
일단 구글링해보니.. Bitmap 때문인것 같습니다..
11-25 15:26:48.603: ERROR/AndroidRuntime(18764): java.lang.OutOfMemoryError: bitmap size exceeds VM budget
요래 뜨거든요..
단순히 이미지 파일을 보여주는것과 달리 Bitmap객체로 만들어 이미지뷰에 뿌려줄때는 뭔가 문제가 있나봅니다 ㅠ
또 구글링 해보니..
((BitmapDrawable)mQuestion.getDrawable()).getBitmap().recycle();
이 문장을 추가하여 recycle 해주면 괜찮다네요..
호출위치는 새로운 이미지를 보여주는 소스 mQuestion.setImageBitmap() 전에 호출을 하구요..
그런데 이젠 또 다른 문제를 뿜으면서 어플이 죽네요..
대충보니 recycle 된 이미지를 다시 사용하는거때문?? 인듯 한데요..
11-25 15:52:01.583: ERROR/AndroidRuntime(19654): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@477673b0
이 문제를 어떻게 해야 할까요;; 일부러 이미지 파일을 만들지 않고 할려고 byte[]데이터로 Bitmap 객체 만들어서 한건데요..
확실한건.. 특정위치에서 어플이 죽는게 아닌것으로 보아 메모리 관련 문제는 확실해 보입니다..
메모리 문제는 참 난감하죠.
전 호출시마다 Bitmap 객체를 생성하여 뿌려주는 것을 권장하고싶네요.
BitmapFactory.option 에 보시면 isSampleSize 라는게 있을것입니다.(기억이 가물가물..)
요놈이 원본 이미지의 크기를 줄여서 가져오는 것이기 때문에
메모리 누수쪽 해결에 도움이 될 것 같습니다.
미리 생성해두지 않고 호출시마다 생성하고 기존에 있던 이미지를 recycle 시켜주게되면
두번째 에러에 관해 고민 안하셔도 될 듯 합니다.
for문으로 System.gc를 5~10번정도 돌려주셔도 좋습니다.
isSampleSize는 검색하면 아주많이 나오니 검색해보시길 추천드립니다 :)
View에 담겨 있는 Drawable을 바로 불러서 recycle()하시면 안됩니다. 캔버스가 그릴대상이 없어졌기 때문에 해당 런타임 예외를 보내는겁니다. 순서를
1. recycle() 할 비트맵을 받아 온다. -> 2. setImageBitmap()으로 새로 이미지를 넣어준다 3. recycle()할 비트맵을 recycle()
이렇게 한번 해보세요
그리고 비트맵을 통째로 인텐트에 담아 날리는건 별로 좋지 않습니다. temp 파일로 저장해서 Uri를 날려서 처리하고 지우는 방식으로 바꾸면 자원관리가 원할할겁니다.
일단 이미지가 너무크면 recycle 소용 없습니다. "OutOfMemoryError bitmap" 구굴링해보세요. bitmap 사이즈가 제한되있어서 그이상 큰 이미지를 로드하면 문제가 생깁니다. 이경우 recycle하더라도 메모리 반납못합니다.
그리고 recycle하면 해당 자원은 반납됍니다. 따라서 imageview같은곳에 표시할수 없습니다. 그러니 "isrecycle"을 적당히 이용해서 recycle됀 bitmap은 사용할때 다시 로드해야합니다.
답변주신분들 먼저 감사합니다.
현재 구조가 DB에 byte[] 형태로 저장되있는 이미지를 불러와 화면에 보여주는 구조입니다..
다음, 이전 버튼 누를때 이미지가 빨리빨리 바뀌어야 하는데 이미지를 보여줄때마다 새롭게 Bitmap 객체를 만들어서 하기에는
DB 로딩속도도 있고 변환속도도 있고.. 약간의 딜레이가 생겨서요..
아무래도 Bitmap 겍체를 만들어서 사용하는 과정에 문제가 있는것 같습니다 ㅜ
현재는 DB에서 먼저 조건에 맞는 이미지를 불러와 Bitmap객체 배열로 만들고 다음 액티비티에서 사용하기 위해 데이터클래스의 static Bitmap[] 에 저장을 합니다.
테스트할때는 먼저 이렇게 한번 실행하고, 다시 처음으로 돌아가 또 한번 실행하고.. 이런식으로 하다보면.. 3번째에 딱 오류뿜네요..
역시.. Bitmap 사용안하고 그냥 파일로 만들어서 하는게 빠를려나요..




bitmap이 recycle 되었는데 image view에서 해당 bitmap에 접근 한 문제네요.
bitmap 할당과 recycle이 바로바로 되고 있나요?
중간에 틈이 생겨서 view가 invalidate 될 여지가 있는지 확인이 필요해 보입니다.