LeakCanary — bu nima, Android-da oqishlarni qidirish kutubxonasi

Muallif: IT Sectr Nashr etilgan: 2026-03-30 O'qish vaqti: 9 daq

LeakCanary — bu Square kompaniyasining Android ilovalarida xotira oqishlarini avtomatik aniqlash uchun ochiq kodli kutubxonasi. U rivojlanish jarayoniga integratsiyalanadi va Activity, Fragment, ViewModel hamda boshqa komponentlarning hayotiy sikolini real vaqtda kuzatib boradi, oqishlar yuz bergan zahoti ular haqida signal beradi. Square Open Source ma'lumotlariga ko'ra, kutubxona minglab loyihalarda qo'llaniladi va Android-da xotira diagnostikasi uchun de-fakto standart hisoblanadi.

Asosiy qaydlar

  • LeakCanary — Android-da xotira oqishlarini avtomatik aniqlash uchun kutubxona.
  • Ish mexanizmi WeakReference va komponent yo'q qilingandan keyin GC-ni qo'lda ishga tushirishga asoslangan.
  • Heap dump oqish aniqlanganda avtomatik yaratiladi va o'rnatilgan analizator tomonidan tahlil qilinadi.
  • Natija — koddagi oqish joyini ko'rsatadigan aniq havolalar zanjiri (leak trace).
  • LeakCanary 2.x qo'lda sozlashni talab qilmaydi — build.gradle-da bitta bog'liqlik yetarli.

LeakCanary nima?

LeakCanary — bu Square kompaniyasi tomonidan ishlab chiqilgan Android ilovalarida xotira oqishlarini avtomatik aniqlash uchun kutubxonadir. U ilova qurish jarayoniga integratsiyalanadi va yo'q qilinishi kerak bo'lgan ob'ektlar (Activity, Fragment, View) xotirada qolib ketganda avtomatik kuzatib boradi. Oqish aniqlanganda, LeakCanary heap dump yaratadi va ob'ektni ushlab turgan havolalar zanjirini tahlil qiladi.

Kutubxona Android jamoasida standartga aylandi: GitHub ma'lumotlariga ko'ra, loyiha 28 mingdan ortiq yulduz to'plagan va Google, Uber, Airbnb va Facebook ilovalarida qo'llaniladi. LeakCanary ikkita asosiy versiyada mavjud: klassik 1.x (qo'lda sozlash bilan) va zamonaviy 2.x (ContentProvider orqali avtomatik integratsiya). 2.x versiyasi Application sinfini o'zgartirishni talab qilmaydi — to'liq ishlash uchun bitta bog'liqlik yetarli.

LeakCanary-ning asosiy vazifasi — ob'ektning hayotiy sikli tugaganidan keyin ham xotirada mavjud bo'lish holatini aniqlash. Bu statik maydonlar, singletonlar, ro'yxatdan o'tkazilmagan callbacklar, anonim sinflar va tashqi ob'ektlarni tutib oluvchi yopilishlar orqali oqishlar uchun xosdir.

Nega LeakCanary Android rivojlanishi uchun muhim

Android-da xotira oqishlari mobil qurilmalardagi cheklangan RAM hajmi tufayli desktop-ga qaraganda muhimroqdir. Har bir ekran almashinuvida atigi 5–10 MB oqish ham ilovadan 30–40 daqiqa foydalanishdan keyin OutOfMemoryError-ga olib kelishi mumkin. LeakCanary bunday muammolarni rivojlanish bosqichida aniqlaydi, ishlab chiqarishdagi nosozlikni kutmasdan.

LeakCanary qanday ishlaydi?

LeakCanary majburiy garbage collector chaqiruvi bilan birgalikda zaif havolalardan (WeakReference) foydalanadi. Activity yoki Fragment onDestroy chaqirganda, LeakCanary ushbu ob'ektga WeakReference yaratadi va qisqa kechikishdan keyin (standart 5 soniya) GC-ni ishga tushiradi. Agar GC-dan keyin ob'ekt hali ham WeakReference orqali mavjud bo'lsa, demak u kuchli havola bilan ushlab turilgan — oqish qayd etiladi.

Oqish aniqlangandan so'ng, LeakCanary heap dump (HPROF formatidagi ilova xotirasining to'liq surati) yaratadi. Keyin o'rnatilgan analizator (2.x versiyasi uchun Shark) GC Roots-dan oqqan ob'ektgacha erishish grafigini quradi va eng qisqa yo'lni — ob'ektni xotirada ushlab turgan havolalar zanjirini topadi.

kotlin
// LeakCanary aniqlash mantiqining soddalashtirilgan versiyasi
class ObjectWatcher {
    private val watchedReferences = CopyOnWriteArrayList<KeyedWeakReference>()

    fun watch(watchedObject: Any, description: String) {
        val reference = KeyedWeakReference(watchedObject, description)
        watchedReferences.add(reference)
        BackgroundHandler.postDelayed({
            checkForLeaks()
        }, 5000)
    }

    private fun checkForLeaks() {
        GcTrigger.runGc() // majburiy GC
        for (ref in watchedReferences) {
            if (ref.get() != null) {
                onLeakFound(ref) // ob'ekt GC dan omon qoldi — bu oqish
            }
        }
    }
}

Asosiy nuqta — majburiy GcTrigger.runGc() chaqiruvidir. Usiz, haqiqatan oqqan ob'ektni GC hali yig'ishga ulgurmagan ob'ektdan farqlash mumkin emas. LeakCanary buni uch martagacha bajaradi: agar uchta GC siklidan keyin ob'ekt hali ham xotirada bo'lsa — oqish tasdiqlanadi.

Shark nima — heap dump analizatori

Shark — bu Kotlin tilida yozilgan LeakCanary 2.x ga o'rnatilgan heap dump analizatoridir. Oldingi HAHA analizatoridan farqli o'laroq, Shark butun HPROF faylini xotiraga yuklamaydi, balki uning ob'ekt grafigini minimal ajratmalar bilan aylanib chiqadi. Bu tahlil paytida RAM iste'molini 50 MB dan 2–5 MB gacha kamaytiradi va tahlil vaqtini 30 soniyadan 1–3 soniyagacha qisqartiradi.

LeakCanary-ni qanday o'rnatish va sozlash?

Zamonaviy Android loyihasida LeakCanary 2.x o'rnatish build.gradle-da bir satrni oladi. Kutubxona avtomatik ishga tushirish uchun ContentProvider-dan foydalanadi — Application sinfini o'zgartirish yoki MainActivity-ga kod qo'shish shart emas. Ulanish faqat debug-build uchun amalga oshiriladi, release APK-da ortiqcha kod bo'lmasligi uchun.

groovy
// build.gradle (app/module)
dependencies {
    // debugImplementation — kutubxona faqat debug-build uchun
    debugImplementation "com.squareup.leakcanary:leakcanary-android:2.14"
}

Bog'liqlik qo'shilgach va loyiha qayta qurilgach, LeakCanary avtomatik ravishda ilovada paydo bo'ladi. Birinchi ishga tushirishda kutubxona faollashtirish haqida tizim bildirishnomasini ko'rsatadi. Barcha aniqlangan oqishlar bildirishnomalar shaklida ko'rsatiladi — bildirishnomaga bosish batafsil hisobot (LeakTrace) ekranini ochadi.

Moslashtirish uchun o'zingizning AppWatcherInstaller-ingizni yaratib, parametrlarni o'zgartirishingiz mumkin: GC kutish muddati, kuzatiladigan ob'ekt turlari ro'yxati, heap dump-ni diskka saqlashni yoqish. Biroq, loyihalarning 90% i uchun standart konfiguratsiya optimaldir.

Koroutinlar va Jetpack Compose uchun sozlash

2.12 versiyasidan boshlab, LeakCanary ViewModel, koroutin skoplari va Compose State ob'ektlarini avtomatik kuzatishni qo'llab-quvvatlaydi. Qo'shimcha bog'liqliklar talab qilinmaydi — kutubxona loyihada qaysi Jetpack komponentlari ishlatilayotganini o'zi aniqlaydi va tegishli detektorlarni faollashtiradi.

LeakCanary hisobotini qanday o'qish kerak

LeakCanary hisoboti (LeakTrace) — bu GC Root-dan oqqan ob'ektgacha bo'lgan ko'p satrli havolalar zanjiridir. Har bir satr kuchli havola o'tadigan sinf va maydonni ko'rsatadi. Dasturchi zanjirni pastdan yuqoriga o'qishi kerak: pastki satr — oqqan ob'ekt, yuqori satr — kirish nuqtasi (GC Root).

Oddiy LeakTrace shunday ko'rinadi: GC Root → statik Application maydoni → singleton → callback → Activity. Agar dasturchi bunday zanjirni ko'rsa, muammo aniq: singleton Activity-ga havolani tutib olgan callbackni ushlab turibdi. Yechim — singletonda kuchli havolani zaif bilan almashtirish.

text
┬
├─ android.app.Application
│    Leaking: NO (Application — singleton)
│    ↓ Application.leakedActivities
├─ java.util.ArrayList
│    Leaking: NO (ArrayList — normal)
│    ↓ ArrayList[0]
├─ com.example.MainActivity
│    Leaking: YES (Activity destroyed but still in memory)
│    ↓ MainActivity.mCallback
├─ com.example.CallbackWrapper
│    Leaking: UNKNOWN
│    ↓ CallbackWrapper.mListener
│              ~~~~~~~~~~
├─ com.example.MyCallback (anonymous)
│    Leaking: UNKNOWN
│    ↓ MyCallback.this$0
├─ com.example.MainActivity
│    Leaking: YES (MainActivity is the leak)
╰

Ushbu misolda LeakCanary MainActivity zanjir orqali ushlab turilganini ko'rsatadi: Application → ArrayList → MainActivity → CallbackWrapper → MyCallback → yana MainActivity. this$0 o'qi anonim MyCallback sinfi Activity-ga tashqi havolani tutib olganini ko'rsatadi. Yechim — callbackni zaif havola qilish yoki uni onDestroy-da bekor qilish.

LeakCanary shuningdek zanjirning har bir elementi uchun oqish holatini ko'rsatadi: NO (oqish yo'q — bu ildiz element), YES (ob'ekt yo'q qilinishi kerak), UNKNOWN (holatni aniqlash imkonsiz). UNKNOWN holati muammo emas — bu LeakCanary bir ma'noda tasniflay olmaydigan oraliq ob'ektdir.

LeakCanary 2.x vs 1.x: asosiy farqlar

1.x versiyasidan 2.x ga o'tish tubdan edi: dasturchilar kutubxonani noldan qayta yozdilar, eskirgan HAHA analizatorini Kotlin tilida yozilgan o'zining Shark dvigateli bilan almashtirdilar. Shark ancha tez ishlaydi, tahlil uchun kam xotira talab qiladi va oqishlarning asosiy sabablarini aniqroq belgilaydi.

ParametrLeakCanary 1.xLeakCanary 2.x
Analizator tiliJava (HAHA — Android SDK forki)Kotlin (Shark — o'z dvigateli)
O'rnatishApplication-da AppWatcher-ni qo'lda sozlashContentProvider orqali avtomatik
TezligiHeap dump tahlili uchun 10–30 soniyaHeap dump tahlili uchun 1–5 soniya
SamaradorligiTahlil paytida 10–50 MB RAMTahlil paytida 2–10 MB RAM

Shark-ning asosiy afzalligi — butun heap dump-ni xotiraga yuklamaydi, balki uning havola grafigini minimal ajratmalar bilan aylanib chiqadi. Bu LeakCanary 2.x ni tahlil paytida OutOfMemoryError xavfisiz kam RAM hajmli qurilmalarda foydalanishga yaroqli qiladi.

2.x versiyasida shuningdek Android Studio Memory Profiler-da keyingi tahlil uchun heap dump-ni faylga eksport qilish imkoniyati paydo bo'ldi. Buning uchun AppWatcher konfiguratsiyasida dumpHeapWhenLeakFound sozlamasini yoqish kerak.

LeakCanary topadigan tipik oqishlar

LeakCanary Android uchun xos bo'lgan bir necha sinf oqishlarni samarali aniqlaydi. Eng ko'p uchraydigan — Activity-ga statik havolalar orqali oqish: dasturchilar Activity kontekstiga havolani singletonda saqlaydi va Activity hayotiy sikli tugaganidan keyin GC tomonidan yig'ila olmaydi.

Chastota bo'yicha ikkinchi kategoriya — ro'yxatdan o'tkazilmagan tinglovchilar orqali oqishlar. Agar onStart-da registerListener chaqirilgan bo'lsa, lekin onStop/onDestroy da unregisterListener chaqirilmagan bo'lsa — tinglovchi ob'ekti aktivlik yo'q qilinganidan keyin ham tizim tomonidan ushlab turiladi. LeakCanary qaysi tinglovchi va qaysi tizim xizmatida faol qolganini bir ma'noda ko'rsatadi.

kotlin
// Tipik oqish: Activity singleton callbackida tutib olingan
object AnalyticsManager {
    private var callback: ((String) -> Unit)? = null

    fun register(callback: (String) -> Unit) {
        this.callback = callback // callbackga kuchli havola
    }

    fun unregister() {
        callback = null // onDestroy-da CHAQIRISHNI UNUTMANG!
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        AnalyticsManager.register { event ->
            logEvent(event) // lambda thisni tutib oladi
        }
        // onDestroy-da unregister chaqirilmasa → Activity oqishi
    }
}

Uchinchi kategoriya — BackStack-dagi Fragment orqali oqishlar. Agar FragmentTransaction.addToBackStack() qaytishda Fragment o'chirilmasdan chaqirilsa, eski Fragment nusxalari xotirada qoladi. LeakCanary rivojlanishning dastlabki bosqichlarida bunday yashirin oqishlarni aniqlashga yordam beradi.

Har bir aniqlangan oqish uchun LeakCanary tavsif va tuzatish bo'yicha tavsiyalar taklif qiladi. 2.14 versiyasida Android Lint bilan integratsiya qo'shilgan — kutubxona CI-da oqish aniqlanganda issue tracker-da avtomatik vazifalar yaratishi mumkin.

Ko'p beriladigan savollar

LeakCanary-ni release APK-dan olib tashlash kerakmi?

Ha, albatta. LeakCanary build.gradle-da debugImplementation orqali ulanadi, bu uni avtomatik ravishda release qurilmasidan chiqarib tashlaydi. Agar implementation orqali ulasangiz, kutubxona release APK-ga tushadi va oxirgi foydalanuvchilarga oqishlarni ko'rsatadi — bu qabul qilib bo'lmaydi.

LeakCanary ilova ishlashini sekinlashtiradimi?

Samaradorlikka ta'siri minimal. LeakCanary faqat komponentning onDestroy-dan keyin faollashadi va UI renderlash yoki teginishlarni qayta ishlashga aralashmaydi. Yagona xarajat — majburiy GC ning qisqa pauzasi (taxminan 100 ms) va oqish paytida heap dump yozuvi (soniyaning yuzdan bir qismi).

LeakCanary hisobotini qanday eksport qilish mumkin?

LeakCanary avtomatik ravishda HPROF formatidagi heap dump-ni ilova papkasida saqlaydi. Faylni Android Studio orqali eksport qilish mumkin: Device File Explorer → data/data/com.example/files/leakcanary/. Ko'rish uchun faylni Memory Profiler-da Capture → Open Heap Dump orqali oching.

LeakCanary Jetpack Compose bilan ishlaydimi?

Ha, 2.12 versiyasidan boshlab LeakCanary Jetpack Compose-ni to'liq qo'llab-quvvatlaydi. Kutubxona Composition kontekstlari va State ob'ektlarini kuzatib boradi, Composable funksiyalaridagi oqishlarni avtomatik aniqlaydi. Alohida sozlash talab qilinmaydi — qutidan chiqqandek ishlaydi.

LeakCanary xato qilishi mumkinmi (false positive)?

Yolg'on faollashuvlar mumkin, lekin kam uchraydi. LeakCanary oqishni e'lon qilishdan oldin uch marta GC chaqiruvidan foydalanadi, bu yolg'on pozitivlarning ko'pchiligini yo'q qiladi. Agar faollashuv yolg'on deb hisoblasangiz — konfiguratsiyada ma'lum sinf uchun IgnoredReference yarating.

Xulosa

  • LeakCanary — Android ilovalarida xotira oqishlarini avtomatik aniqlash uchun standart kutubxona.
  • Kutubxona hayotiy siklidan o'tgan ob'ektlarni aniqlash uchun WeakReference va majburiy GC dan foydalanadi.
  • Heap dump GC Root-dan oqqan ob'ektgacha havolalar zanjirini quradigan o'rnatilgan Shark dvigateli tomonidan tahlil qilinadi.
  • Zamonaviy loyihada o'rnatish — build.gradle-da bir satr: debugImplementation.
  • LeakCanary 2.x butunlay Kotlin-da qayta yozilgan va avvalgi versiyadan 5–10 marta tezroq.
  • Eng ko'p uchraydigan oqishlar: Activity-ga statik havolalar, ro'yxatdan o'tkazilmagan tinglovchilar va BackStack-dagi Fragment.
  • Har bir loyihaning debug-build-iga LeakCanary-ni joriy qiling — bu ishlab chiqarishda oqishlarning oldini oladi.

Biz kalit topshirig'i bilan mobil ilovani ishlab chiqamiz

IT Sectr 2017-yildan beri startaplar va korxonalar uchun iOS va Android ilovalarini yaratadi. Biz sizga maslahat beramiz va eng yaxshi yechimni taklif qilamiz.

Loyihani muhokama qilish

Shuningdek o'qing