-
[Project/Android] `OutOfMemoryError` 오류 해결하기Daily/Project 2023. 12. 19. 15:52728x90
1. Physical 안드로이드 기기 테스트 중 오류
안드로이드 스튜디오에서 제공하는 Virtual(가상) 안드로이드 기기가 아닌,
Physical(실제) 안드로이드 기기에서 테스트하던 중 다음과 같은 에러가 발생하였습니다.
java.lang.OutOfMemoryError:
Failed to allocate a 23425512 byte allocation with 16766392 free bytes and 21MB until OOM주목해야 할 단락은 위 메시지입니다. 해당 오류 메시지에서는 23,425,512 바이트를 할당하려고 했지만,
현재 사용 가능한 메모리가 16,766,392 바이트 밖에 남아있지 않다는 것을 나타냅니다.
이에 따라 시스템은 OutOfMemoryError를 발생시켰습니다.
2. 해결하는 방법
"사용자 경험(UX)이 더 중요할까, 성능이 더 중요할까?" 저는 방법을 모색하던 도중 선택의 기로에 서게 되었습니다.
빠른 이미지 로드로 사용자 경험 향상하기 그리고 메모리나 디스크 사용의 최소화 중
어떤 것을 선택해야 할지 고민하게 되었습니다.
음... 앱이 잘 돌아가야 하니, 성능에 높은 우선순위를 두고 코드를 수정해 보도록 하죠.
자세히 보니 이런 코드가 로그가 있더군요. 이 파일을 수정해야겠습니다.
at com.three.green_defense_force.activities.GameDetailActivity.onCreate(GameDetailActivity.kt:50)
2-1. 메모리 관리 코드 추가하기
메모리 캐시를 사용하지 않도록 설정하였습니다. 이미지를 메모리에 캐싱할 경우 동일한 이미지를 빠르게 다시 로드할 수 있지만, 메모리 사용량이 높아지기 때문에 이를 해제시키도록 하겠습니다.
.skipMemoryCache(true)
Before
private fun loadImageFromUrl(url: String, imageView: ImageView) { Glide.with(this) .load(url) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(imageView) }
After
private fun loadImageFromUrl(url: String, imageView: ImageView) { Glide.with(this) .load(url) .thumbnail(0.1f) .skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.ALL) .into(imageView) }
해결... 완료... ⭐️ 그럼 이만 마치 도로ㄱ... 이게 아니죠.. skipMemoryCache(true)가 무엇인지조금 더 보도록 하겠습니다.
3. skipMemoryCache(true)
skipMemoryCache는 Glide의 메모리 캐시를 비활성화하는 옵션입니다.
Glide는 이미지를 메모리에 캐시 하여 동일한 이미지를 빠르게 로드하도록 하지만,
가끔 큰 이미지를 다뤄야 할 때 메모리 부족 문제가 발생할 수 있습니다.
skipMemoryCache(true)를 사용하면 Glide는 해당 이미지를 메모리에 캐시 하지 않고 디스크에만 캐시 하게 됩니다.
(디스크에 캐시를 할지 말지도 선택할 수 있죠. 뒤에서 다루겠습니다.)
⛔️ 주의사항 ⛔️
그러나 메모리 캐시를 건너뛰면 이미지를 다시 로드할 때마다 네트워크 또는 로컬 디스크에서 이미지를 읽어와야 하므로
성능이 약간 감소할 수 있습니다.
4. 해결한 코드 꼼꼼히 살펴보기
/** URL → 이미지 변환하는 함수 */ private fun loadImageFromUrl(url: String, imageView: ImageView) { Glide.with(this) .load(url) // Glide로 이미지 URL 로드 .thumbnail(0.1f) // 이미지 로딩 속도 향상 .skipMemoryCache(true) // 메모리 캐시 사용 X .diskCacheStrategy(DiskCacheStrategy.ALL) // 모든 이미지를 디스크에 캐싱 .into(imageView) // ImageView에 이미지 설정 }
모든 이미지를 디스크에 캐싱하도록 설정하였습니다. 이미지를 디스크에 캐싱하여, 동일한 URL의 이미지에 대한 반복 다운로드를 방지하고 로딩 시간을 단축할 수 있습니다.
.diskCacheStrategy(DiskCacheStrategy.ALL)
5. 결론
.skipMemoryCache(true) .diskCacheStrategy(DiskCacheStrategy.ALL)
이 두 옵션을 함께 사용하는 경우, 메모리 측면에서는 캐싱을 하지 않고, 디스크 측면에서는 캐싱을 하게 됩니다.이를 통해 메모리 사용을 최소화하면서도 디스크 캐싱의 이점을 얻을 수 있습니다.
'Daily > Project' 카테고리의 다른 글
[개인 프로젝트] 내가 사용하기 위한 앱 만들기 (Feat. 집중을 위한 앱) (1) 2024.05.12 [Project/Android] GameActivity 만들기 (Feat. 조이스틱 만들기) (2) 2023.12.14 [Project/Android] `도전! 환경 지킴 방범대` 프로젝트 1 (Feat. 소개) (0) 2023.12.12