Garbage Collection(GC)

eunsong·2024년 12월 27일

Android

목록 보기
9/9
post-thumbnail

안드로이드에서 GC가 중요한 이유

1. 제한된 자원과 OOM 크래시

  • 모바일 디바이스는 메모리가 제한적이며, 과도한 메모리 사용은 OOM 크래시로 이어질 수 있습니다.
  • 안드로이드 앱의 메모리 한도는 디바이스와 Android OS버전에 따라 다르며, 초과할 경우 강제로 종료됩니다.

2. GC로 인한 성능 저하

  • GC 작업은 메인 스레드를 차단시킬 수 있으며, 이는 프레임 드롭이나 UI 렉(lag)을 유발합니다.
  • 잦은 GC 호출은 CPU 작업량을 증가시키며, 배터리 소모를 가속화할 수 있습니다.

3. 지속적인 메모리 관리 요구

  • 안드로이드에서는 Activity, Fragment, Bitmap 등 많은 객체가 동적으로 생성되고 제거됩니다.
  • 이러한 객체들이 적시에 해제되지 않으면 메모리 누수가 발생하며, 앱 성능에 영향을 미칩니다.

GC(Garbage Collection)의 작동 원리

1. GC란?

Garbage Collection(GC)은 더 이상 사용되지 않는 객체를 탐지하고 메모리에서 해제하여, 새 객체를 저장할 수 있는 공간을 확보하는 프로세스입니다.

GC의 주요 목표는 메모리 누수 방지효율적인 메모리 관리입니다.


2. 객체 생존 주기와 Reachability

GC는 객체가 더 이상 사용되지 않을 때 해당 객체를 메모리에서 제거합니다. 객체가 사용 중인지 여부는 참조(reference)를 기준으로 판단합니다.

Root 참조

  • Java의 GC Root는 JVM이 직접 참조하는 객체로, 여기서 시작해 참조 체인을 탐색하여 객체의 생존 여부를 판단합니다.
  • GC Root에 포함되는 예
    • Static 변수로 선언된 객체
    • 활성 스레드의 참조
    • JNI(Java Native Interface) 참조되는 객체

Mark-and-Sweep 알고리즘

GC는 Mark-and-Sweep 알고리즘을 사용하여 객체를 정리합니다.

  1. Mark 단계 : GC Root에서 시작해, 도달할 수 있는 모든 객체를 탐색하고 '생존'표시를 남깁니다.
  2. Sweep 단계 : '생존'표시가 없는 객체를 메모리에서 제거합니다.

3. 힙 메모리 구조

GC는 힙 메모리(Heap Memory)를 관리합니다. 힙 메모리는 아래와 같이 세 가지 영역으로 나뉩니다.

Young Generation

  • 새로 생성된 객체가 저장되는 영역
  • 대부분의 객체는 여기서 빠르게 수명이 끝난다.
  • Minor GC가 자주 발생하며, Young Generation의 메모리를 정합니다.

Old Generation(Tenured Generation)

  • Young Generation에서 살아남은 객체가 이동되는 영역
  • 상대적으로 큰 메모리를 차지하며, Major GC로 정리됩니다.

Permanent Generation / Metaspace

  • JVM 메타데이터와 클래스 정보를 저장
  • 최신 JVM에서는 Metaspace로 대체되었습니다.

GC와 관련된 주요 문제

1. 메모리 누수 원인

  • activity 나 fragment 의 참조가 강한 참조로 유지되어 GC가 객체를 정리하지 못하는 경우
  • Hnadler, AsyncTask 와 같은 구성 요소에서 부적절한 참조.

[해결방법]

  • WeakReference 를 사용해 강한 참조를 방지
  • LeakCanary 로 메모리 누수 탐지하고, 누구 객체의 힙 덤프를 분석합니다.

2. 비효율적인 객체 생성

  • 반복적으로 동일한 객체를 생성하거나 대규모 컬렉션 객체를 유지
  • UI 요소에서 과도한 View 인스턴스 생성

[해결방법]

  • Object Pooling: 빈번히 사용되는 객체를 재사용하여 불필요한 메모리 할당을 줄임
  • ViewHolder 패턴: RecyclerView 에서 ViewHOlder 를 활용하여 View 재사용을 최적화
  • Lazy Initialization: 필요한 시점에만 객체를 초기화

3. Bitmap 메모리 관리

  • Bitmap 객체는 메모리를 많이 차지하며, 적절히 관리하지 않으면 OOM이 발생

[해결방법]

  • Glide, Coil: Bitmap을 효율적으로 로드하고 캐싱
  • 이미지 크기 조정
  • Native 메모리 해제 : Bitmap 객체를 사용한 후 recycle() 메서드로 메모리 해제

4. GC 빈도 줄이기

  • GC가 자주 발생하면 CPU 사용량이 증가하고 UI 성능이 저하

[해결방법]

  • 불필요한 객체 생성 방지 : 전역 객체나 static 변수로 공유 가능한 데이터는 재사용
  • 컬랙션 초기 용량 설정
  • 메모리 프로파일링: Android Studio Profiler 를 사용해 메모리 사용 패턴을 분석

5. 안드로이드 GC 최적화 Best Practices

  1. 메모리 누수 방지
  • Context를 잘못 참조하지 않도록 주의(Activity 대신 Application Context 사용).
  • 리스너, 콜백 등을 적절히 해제.
  1. 이미지 메모리 최적화
  • 리소스 크기를 동적으로 조정.
  • 캐싱 라이브러리 활용(Glide, Coil).
  1. 객체 재사용
  • 데이터 구조와 알고리즘을 최적화하여 불필요한 객체 생성을 최소화.
  1. 애니메이션 최적화
  • GPU 렌더링을 활용하고, UI 스레드에서 작업 최소화.
profile
A place to study and explore my GitHub projects: github.com/freeskyES

0개의 댓글