본문 바로가기

개발 이야기

[Android] Leak Canary를 이용하여 메모리 누수개선방안

320x100

LeakCanary는 앱에서 메모리 누수를 감지해주는 라이브러리입니다. 안드로이드 앱에서 LeakCanary를 사용하여 메모리 누수를 찾는 방법을 설명하겠습니다.

1. LeakCanary 추가

앱 프로젝트의 build.gradle 파일에 LeakCanary 종속성을 추가합니다. 새로운 버전의 LeakCanary가 존재할 수 있으므로, LeakCanary GitHub 저장소에서 최신 버전을 확인하세요.

dependencies {
  // LeakCanary 종속성 추가
  debugImplementation 'com.squareup.leakcanary:leakcanary-android:{latest-version}'
}

2. LeakCanary 초기화

Application 클래스를 만들고 여기서 LeakCanary를 초기화합니다. 기존의 Application 클래스가 있다면 거기에 추가하세요.

import android.app.Application
import leakcanary.LeakCanary

class MyApplication : Application() {
  override fun onCreate() {
    super.onCreate()

    // LeakCanary 초기화
    if (LeakCanary.isInAnalyzerProcess(this)) {
      return
    }
    LeakCanary.install(this)
  }
}

3. AndroidManifest.xml 에 Application 클래스 등록

AndroidManifest.xml에서 Application 클래스를 등록합니다. 기존에 Application 클래스가 있다면 이 과정을 건너뛰세요.

<application
  android:name=".MyApplication"
  ...>
  ...
</application>

4. 앱에서 메모리 누수 감지

LeakCanary를 구성하고 나면 앱에서 메모리 누수를 자동으로 감지하게 됩니다. 앱을 사용하다가 메모리 누수가 발생하면, LeakCanary가 알림을 표시하고 메모리 누수 분석을 시작합니다. 분석이 완료되면 다시 알람이 표시되고, 해당 알람을 클릭하여 메모리 누수에 대한 정보를 확인할 수 있습니다.

┬───
│ GC Root: System class

├─ leakcanary.internal.InternalLeakCanary class
│ Leaking: NO (it's a GC root)
│ ↓ static InternalLeakCanary.resumedActivity

~
├─ com.example.myapplication.MainActivity instance
│ Leaking: YES (ObjectWatcher was watching this because com.example.myapplication.MainActivity received Activity#onDestroy() callback and Activity#mDestroyed is true)
│ ↓ MainActivity.textView
│ ~


├─ androidx.appcompat.widget.AppCompatTextView instance
│ Leaking: YES (RefWatcher was watching this because com.example.myapplication.MainActivity$onCreate$1 was passed to RefWatcher.watch and MainActivity#mDestroyed is true)
│ mContext instance of com.example.myapplication.MainActivity with mDestroyed = true
│ View.parent com.android.internal.policy.DecorView with mAttachInfo = androidx.appcompat.view.View_AttachInfo@5cc1a1
│ View.mID=R.id.textView
│ View.mWindowAttachCount=1
│ ↓ AppCompatTextView.mContext
╰→ com.example.myapplication.MainActivity instance
​ Leaking: YES (AppCompatTextView↑ is leaking and Activity#mDestroyed is true and ObjectWatcher was watching this)
​ mContext instance of com.example.myapplication.MainActivity with mDestroyed = true
​ View.parent com.android.internal.policy.DecorView with mAttachInfo = androidx.appcompat.view.View_AttachInfo@5cc1a1
​ View.mID=R.id.textView
​ View.mWindowAttachCount=1
​ ↓ MainActivity.binding$delegate

~


​ ├─ androidx.viewbinding.ViewBinding instance
​ │ Leaking: YES (MainActivity↑ is leaking and Activity#mDestroyed is true)
​ │ ViewBinding#root mView with ID 0x7f09006b (com.example.myapplication:id/textView) is null (View detached)
​ │ View#mParent=com.android.internal.policy.DecorView{30a4d52 V.E...... ......I. 0,0-720,1344} {...}
​ │ View#mAttachInfo=null
​ │ View.mWindowAttachCount=1
​ │ ↓ ViewBinding.root
​ ╰→ null

5. 메모리 누수 정보 확인 및 해결

LeakCanary 알림에 표시되는 메모리 누수 정보를 사용하여 해당 이슈를 해결합니다. 이 정보에는 클래스 이름, 누수량, 지속 시간 등의 세부 사항이 포함되어 있어 누수 원인을 찾는 데 도움이 됩니다. 메모리 누수는 종종 개방된 리소스, 콜백 등을 올바르게 정리하지 않거나 데이터 구조 변경 등으로 인해 발생할 수 있습니다. 앱 코드를 검토하여 연관된 문제를 정리하고 누수를 해결합니다.

LeakCanary를 통해 메모리 누수를 감지하고, 이를 해결하여 앱의 성능을 향상시킬 수 있습니다. 사용하기 쉽고 강력한 도구로, 개발 과정에서 앱의 안정성을 확보하는 데 큰 도움이 됩니다.

반응형