Glide 캐시 및 로드 시스템 정리

Glide의 이미지 로딩 및 캐싱 시스템을 이해하기 위한 정리입니다. Glide는 고성능 이미지 로딩을 위한 Android용 라이브러리로, 메모리 및 디스크 캐시, 비트맵 재사용, 요청 최적화 등을 지원합니다.

 

메모리 캐시 (MemoryCache)

  • Glide는 LruResourceCache를 통해 LRU(Least Recently Used) 방식의 메모리 캐시를 제공합니다.
  • 기본 크기는 MemorySizeCalculator에 의해 자동 결정되며, RAM 용량, 화면 해상도 등을 고려합니다.
  • setMemoryCacheScreens(n)으로 n개의 화면 분량의 이미지를 캐싱할 수 있도록 커스터마이징 가능합니다.
@GlideModule
class YourAppGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
val calculator = MemorySizeCalculator.Builder(context)
.setMemoryCacheScreens(2f)
.build()
builder.setMemoryCache(LruResourceCache(calculator.memoryCacheSize.toLong()))
}
}

 

비트맵 풀 (Bitmap Pool)

  • Glide는 LruBitmapPool을 사용하여 비트맵 객체를 재사용합니다.
  • LRU 정책을 통해 오래된 비트맵부터 제거하여 메모리 최적화를 유도합니다.
  • setBitmapPoolScreens(n)으로 풀 사이즈 조정 가능.
@GlideModule
class YourAppGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
val calculator = MemorySizeCalculator.Builder(context)
.setBitmapPoolScreens(3f)
.build()
builder.setBitmapPool(LruBitmapPool(calculator.bitmapPoolSize.toLong()))
}
}

 

디스크 캐시 (DiskCache)

  • 기본 구현은 DiskLruCacheWrapper로, 기본 캐시 용량은 250MB
  • 앱의 캐시 디렉터리에 저장되며, 필요 시 내부/외부 위치 및 크기 커스터마이징 가능
  • 디스크 캐시 초기화는 백그라운드 스레드에서 이루어지며, 이는 메인 스레드에서의 I/O로 인한 StrictMode 위반을 방지하기 위함입니다. StrictMode는 메인 스레드에서의 긴 작업이나 I/O를 감지하여 경고를 발생시키는 Android의 기능입니다. 
@GlideModule
class YourAppGlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
val diskCacheSizeBytes = 1024 * 1024 * 100 // 100 MB
builder.setDiskCache(InternalCacheDiskCacheFactory(context, diskCacheSizeBytes.toLong()))
}
}

 

기본 요청 옵션 설정

  • AppGlideModule에서 setDefaultRequestOptions를 통해 앱 전체에 적용할 옵션 설정 가능.
  • applyDefaultRequestOptions를 사용하면 특정 Activity 또는 Fragment에만 적용되는 기본 RequestOption을 설정할 수 있다.
Glide.with(fragment)
.applyDefaultRequestOptions(
RequestOptions()
.format(DecodeFormat.RGB_565)
.disallowHardwareBitmaps()
)

setDefaultRequestOptions 사용 시 주의점

setDefaultRequestOptions는 다른 곳에서 설정 한 중요한 기본값을 실수로 재정의하기 쉽기 때문에 주의해야한다. 일반적으로 applyDefaultRequestOptions가 사용하기에 더 안전하고 직관적이다.

 

 

예외 처리 전략 (UncaughtThrowableStrategy)

  • Glide는 OutOfMemoryError 같은 예외 발생 시 대응 전략을 설정할 수 있는 UncaughtThrowableStrategy를 제공합니다.
  • UncaughtThrowableStrategy는 Glide의 실행 중 예기치 않은 예외가 발생했을 때의 처리 전략을 
    • IGNORE: 예외를 무시
    • LOG: 예외를 로그에 기록
    • THROW: 예외를 다시 던져 앱을 크래시
  • 4.2.0 이전은 LOG이며 4.2.0 이후부터 IGNORE, LOG, THROW 중 선택 가능

 

  • Disk Executor: 디스크 캐시 작업을 처리하는 스레드 풀입니다.
  • Resize Executor: 이미지 리사이징 작업을 처리하는 스레드 풀입니다.

이러한 Executor는 Glide의 내부 작업을 비동기적으로 처리하여 앱의 성능을 향상시킵니다 .

 

컴포넌트 등록

 

Glide에서의 컴포넌트는 이미지 로딩 및 처리 과정의 각 단계를 담당하는 모듈입니다.

  • ModelLoader: 데이터 소스(예: URL, 파일 등)를 처리합니다.
  • ResourceDecoder: 데이터를 비트맵 등으로 디코딩합니다.
  • Encoder: 데이터를 디스크 캐시에 저장합니다.
  • ResourceTranscoder: 리소스를 다른 형식으로 변환합니다.
  • ResourceEncoder: 리소스를 디스크 캐시에 저장합니다.

 

Glide는 등록된 여러 ModelLoader와 ResourceDecoder 중에서 적절한 것을 선택하여 사용합니다. 

이때, Registry의 prepend(), append(), replace() 메서드를 사용하여 우선순위를 조정할 수 있습니다.

 

  • catch-all 컴포넌트: 모든 상황을 처리하는 기본 구성 요소
  • 서브셋트 컴포넌트: 특정 데이터 조건에만 적용되는 구성 요소

 

예를 들어, 특정 도메인의 URL에만 적용되는 ModelLoader를 서브셋트로 등록하고, 그 외의 경우에는 catch-all 컴포넌트를 사용하도록 설정할 수 있습니다 .

 

로드 경로의 이해

Glide는 이미지를 로드할 때 먼저 캐시에 있는지 확인하고, 없으면 아래 순서대로 처리합니다

    • [1] 메모리 캐시 확인 (LruResourceCache)
          ↓ 캐시에 있으면 즉시 반환
          ↓ 없으면 다음 단계 진행
      [2] 디스크 캐시 확인 (RESOURCE / DATA)
          ↓ 있으면 디코딩해서 메모리 캐시에 다시 저장
          ↓ 없으면 다음 단계로 실제 로드 진행
      [3] 로드: Model → Data → Resource → Transcoded Resource
          ↓
      [4] 캐싱
          - 디스크 캐시 저장 (Encoder, ResourceEncoder)
          - 메모리 캐시 저장 (ResourceCache)

 

로드 과정

  • Model → Data
    • 예: URL, File 등을 InputStream 형태의 데이터로 변환
    • 담당: ModelLoader
  • Data → Resource
    • 예: InputStream을 Bitmap 등으로 디코딩
    • 담당: ResourceDecoder
  • Resource → Transcoded Resource
    • 예: Bitmap → Drawable 등으로 변환
    • 담당: ResourceTranscoder (asDrawable() 등 호출 시)
  • Encoder / ResourceEncoder
    • 디코딩된 데이터 or 리소스를 디스크 캐시에 저장
    • 다음 로딩 시 빠르게 가져올 수 있도록 함