OutOfMemoryError — Java Virtual Machine (JVM) yoki Android Runtime (ART) yig‘indida (Heap) joy yo‘qligi sababli yangi obʼekt uchun xotira ajrata olmaganda yuzaga keladigan halokatli istisnodir. Square Engineering maʼlumotlariga ko‘ra, mobil ilovalardagi OutOfMemoryError-larning 70% xotira oqishlari sababli yuzaga keladi, haqiqiy limitdan oshib ketish tufayli emas. OOM sabablarini tushunish ilovaning barqaror ishlashi kalitidir.
Asosiy maʼlumotlar
OutOfMemoryError (OOM) — Java/Kotlin-dagi VirtualMachineError oilasiga mansub bo‘lgan va yangi obʼekt uchun xotira ajratish mumkin emasligini bildiruvchi istisnodir. Tekshiriladigan istisnolardan farqli o‘laroq, OOM Error hisoblanadi va catch orqali ishlov berishni talab qilmaydi — texnik jihatdan uni tutish mumkin bo‘lsa-da. OOM yuz bergandan so‘ng, ilova odatda beqaror holatda bo‘ladi va uni tugatish tavsiya etiladi.
Android-da har bir ilova ishlab chiqaruvchi tomonidan belgilangan Heap limitiga ega. 6+ GB RAM-li zamonaviy smartfonlar uchun limit 256–512 MB, byudjet qurilmalari uchun — 128–192 MB ni tashkil qiladi. Barcha tirik obʼektlarning umumiy hajmi ushbu limitdan oshib ketganda, ART OutOfMemoryError ni chiqaradi.
Muhim tushunish: OOM har doim qurilmadagi jismoniy xotira tugaganligini anglatmaydi. Bu ilova tizim tomonidan belgilangan Heap limitini tugatganligini anglatadi. Boshqa ilovalarda bo‘sh xotira bo‘lishi mumkin, ammo Android-dagi jarayon izolyatsiyasi tufayli sizning ilovangiz undan foydalana olmaydi.
Besh stsenariy muntazam ravishda mobil ilovalarda OOM ga olib keladi. Har bir stsenariy maʼlum maʼlumot turi yoki operatsiya bilan bog‘liq.
Bitmap — Android ilovalarida xotiraning asosiy isteʼmolchisi. FullHD tasvirni (1920 × 1080) asl hajmda yuklash ARGB_8888 formatida 8.3 MB ni egallaydi. Agar RecyclerView-da 50 ta bunday tasvir bo‘lsa — bu 415 MB, bu har qanday qurilmaning Heap dan oshib ketadi. Tasvirlarni inSampleSize siz yuklash — kuchsiz qurilmalarda kafolatlangan OOM.
Avtomatik masshtablash uchun Glide yoki Coil dan foydalaning. Ushbu kutubxonalar tasvirlarni asl rezolyusiyada emas, balki View ga mos keladigan o‘lchamda yuklaydi. BitmapFactory.Options dan to‘g‘ridan-to‘g‘ri foydalanish uchun inSampleSize ni qo‘llang: uni ikkining darajasi sifatida hisoblang, shunda yakuniy o‘lcham 2048 × 2048 pikseldan oshmasin. Shaffofligi bo‘lmagan tasvirlar uchun ARGB_8888 o‘rniga RGB_565 dan foydalaning — bu xotira isteʼmolini ikki baravar kamaytiradi.
fun loadScaledBitmap(path: String, reqWidth: Int): Bitmap? {
val opts = BitmapFactory.Options().apply {
inJustDecodeBounds = true
}
BitmapFactory.decodeFile(path, opts)
opts.inSampleSize = calculateSampleSize(opts.outWidth, reqWidth)
opts.inJustDecodeBounds = false
return BitmapFactory.decodeFile(path, opts)
}
Bir necha KB lik oqish OOM ga sabab bo‘lmaydi. Ammo har bir ekranda o‘nlab oqishlar to‘planadi: har bir ekranga o‘tish oqishni qo‘shadi, GC obʼektlarni bo‘shata olmaydi, Heap to‘ladi. Oddiy namuna: foydalanuvchi profil ekranini 20 marta ochadi va yopadi → Heap 200 MB ga o‘sadi → ilova OOM bilan qulab tushadi.
Avtomatik oqishlarni aniqlash uchun loyihaga LeakCanary ni o‘rnating. U aniq stack trace bilan har bir oqayotgan obʼektni ko‘rsatadi. Barcha oqishlar tuzatilgandan so‘ng, Heap isteʼmoli barqaror bo‘ladi: ekran yopilgandan so‘ng xotira asosiy darajaga qaytadi.
Fayllarni to‘liq byte[] ga yuklash — OOM ga to‘g‘ri yo‘l. 50 MB li JSON fayli parsings jarayonida bir xil o‘lchamdagi string va DOM modelini yaratadi. Xotiraga yuklangan video fayllar, audio buferlar va katta protobuf maʼlumotlar to‘plami — barchasi bir operatsiyada Heap limitini oshib ketishi mumkin.
Katta maʼlumotlarni oqimlar bilan qayta ishlang: 4–8 KB buferli InputStream, Streaming JSON-parser (Jackson yoki Gson JsonReader bilan), video uchun MediaCodec. Hech qachon mavjud Heap ning 10% idan katta fayllarda File.readBytes() ni chaqirmang.
Siklda intensiv obʼekt yaratish, oraliq GC siz, ayniqsa kichik Heap li qurilmalarda OOM ga olib kelishi mumkin. Misol: for siklida GC yig‘ishga ulgurmaydigan 100 000 obʼektni yaratish. Bu ko‘pincha o‘yinlar va grafik muharrirlarda uchraydi.
Ommaviy ravishda yaratiladigan va yo‘q qilinadigan obʼektlar uchun Object Pool dan foydalaning. Raqamli maʼlumotlar uchun ibtidoiy turlardan foydalaning (List<Float> o‘rniga FloatArray). ViewHolder Pool bilan RecyclerView UI komponentlari uchun ushbu muammoni hal qiladi.
Fragmentatsiya — umumiy bo‘sh xotira yetarli bo‘lgan, ammo yangi obʼekt uchun uzluksiz blok mavjud bo‘lmagan holat. ART GC vaqtida Heap ni ixchamlashtiradi, lekin har doim ham muvaffaqiyatli emas. Katta massivlar (Bitmap, byte[]) fragmentatsiyaga eng sezgir hisoblanadi.
Android 8+ dagi ART yosh va keksa obʼektlarni ajratish orqali fragmentatsiyani kamaytiradigan Generational GC dan foydalanadi. Shunga qaramay, bitta hovuzda turli o‘lchamdagi fragmentlarni ajratishdan qoching — barqaror o‘lchamdagi oldindan ajratilgan buferlardan foydalanishga harakat qiling.
Heap limiti Android-da doimiy emas — ishlab chiqaruvchiga, qurilma modeliga va OS versiyasiga bog‘liq. Google Compatibility Definition Document (CDD) orqali minimal talablarni belgilaydi, ammo ishlab chiqaruvchilar haqiqiy qiymatlarni o‘rnatadi.
| Qurilma kategoriyasi | Odatiy Heap | largeHeap |
|---|---|---|
| Byudjet (1–2 GB RAM) | 128–192 MB | 256–384 MB |
| O‘rta (3–4 GB RAM) | 256–384 MB | 512 MB |
| Flagman (6+ GB RAM) | 384–512 MB | 768 MB–1 GB |
| Planshetlar (4+ GB RAM) | 256–512 MB | 768 MB |
| Wear OS | 32–64 MB | Yo‘q |
Oshirilgan limitni manifestda android:largeHeap="true" orqali so‘rash mumkin. Ehtiyotkorlik bilan foydalaning: Heap ni oshirish oqish muammosini hal qilmaydi va tizim boshqa ilovalarni o‘ldirishga majbur bo‘lsa, foydalanuvchi tajribasini yomonlashtirishi mumkin. Wear OS uchun Heap limiti minimal — atigi 32–64 MB, bu yerda largeHeap mavjud emas va xotira tejash ikki baravar muhim.
OOM diagnostikasi Heap Dump tahlili va qaysi obʼektlar xotirani isteʼmol qilishini tushunishni talab qiladi. Android Studio barcha kerakli vositalarni taqdim etadi.
1-qadam: OOM momentini qo‘lga oling. Android Memory Profiler-da Record memory allocations tugmasini bosing va qulashga sabab bo‘ladigan stsenariyni bajaring. Profiler OOM dan oldin alokatsiya sakrashini ko‘rsatadi. Agar OOM takrorlanmasa, debug-build da android:smallHeap orqali Heap ni kamaytiring yoki qo‘lda GC chaqiruvi bilan DDMS dan foydalaning.
2-qadam: Eng yuqori yuklanish vaqtida (OOM dan oldin) Heap Dump oling. Dump ni Android Studio-da oching: Classes yorlig‘i Retained Size bo‘yicha tartiblangan. Eng katta obʼektlar — Bitmap, byte[], String. Har bir Bitmap uchun o‘lchamni (width × height × 4 bayt) va Stack Trace orqali yuklash yo‘lini tekshiring.
3-qadam: Takrorlanuvchi obʼektlar sonini tahlil qiling. Agar 200 ta bir xil Fragment yoki Activity ko‘rsangiz — bu oqish. Agar bir xil o‘lchamdagi 500 ta Bitmap bo‘lsa — tasvir keshlash muammosi. MAT (Memory Analyzer Tool) Heap ning 80% ini ushlab turgan obʼektlarni ko‘rsatuvchi Dominator Tree bilan chuqurroq tahlilni taqdim etadi.
// Heap Dump uchun buyruq adb orqali
adb shell am dumpheap com.example.app /data/local/tmp/dump.hprof
adb pull /data/local/tmp/dump.hprof.
Kompleks OOM oldini olish strategiyasi beshta himoya darajasini o‘z ichiga oladi: arxitektura yechimlaridan tortib ishlab chiqarish monitoringigacha.
ViewModel + Repository namunasi maʼlumotlarni UI dan ajratadi va ekran aylantirilganda View ni ushlab qolishning oldini oladi. ViewModel Activity dan uzoqroq yashaydi, uning maʼlumotlari yo‘qolmaydi va View xotirada maʼlumotlarni takrorlamasdan qayta yaratilishi mumkin. Holatlarni boshqarish uchun LiveData o‘rniga StateFlow dan foydalaning.
Glide — tasvirlar bilan ishlash uchun majburiy kutubxona. U avtomatik ravishda masshtablaydi, keshlaydi (disk + xotira) va Bitmap ni recycl qiladi. Katta ro‘yxatlar uchun diskCacheStrategy va skipMemoryCache ni sozlang. Animatsion tasvirlar uchun Glide ni GIF/WebP bilan ishlating — ular Bitmap ketma-ketligiga qaraganda kamroq xotira egallaydi.
Firebase Performance Monitoring xotira isteʼmolini real vaqtda kuzatadi. Heap limitning 80% idan ortiq bo‘lganda ogohlantirish o‘rnating — bu tekshirish signalidir. Crashlytics OOM ni istisno sifatida yig‘adi va qulashdan oldin oxirgi Heap holatini ko‘rsatadi. Android 11+ uchun OOM tugatishlarini aniqlash uchun ApplicationExitInfo dan foydalaning.
Majburiy ravishda ilovani minimal Heap (128–192 MB) bo‘lgan qurilmalarda sinovdan o‘tkazing. Kichik ekranli va kichik Heap li emulyator byudjet qurilmasini simulyatsiya qiladi. Agar ilova bunday qurilmada ishlasa, flagmanlarda OOM muammosi bo‘lmaydi. Turli narx kategoriyalaridagi real qurilmalar bilan Firebase Test Lab dan foydalaning.
// Og‘ir operatsiyadan oldin mavjud Heap ni tekshirish
fun canAllocate(requiredBytes: Long): Boolean {
val runtime = Runtime.getRuntime()
val free = runtime.freeMemory()
return free > requiredBytes * 2 // 50% zaxira
}
Tez-tez beriladigan savollar
Texnik jihatdan ha, ammo buni qilish tavsiya etilmaydi. OOM dan so‘ng ilova beqaror holatda bo‘ladi: yangi alokatsiyalar ishlamasligi mumkin, baʼzi obʼektlar qisman yaratilgan bo‘lishi mumkin. Catch dagi yagona oqilona harakat — loglash va Activity ni qayta ishga tushirish.
Heap limiti turli qurilmalarda farq qiladi. 300 MB talab qiladigan operatsiya 192 MB limitli qurilmada qulab tushadi, lekin 512 MB li flagmanda ishlaydi. OOM stsenariylarini aniqlash uchun minimal xususiyatli qurilmalarda sinov o‘tkazing.
largeHeap limitni oshiradi, lekin ilovani tezlashtirmaydi. GC pauzalari uzoqroq bo‘ladi, chunki katta Heap ni yig‘ish ko‘proq vaqt oladi. Tizim xotirani taʼminlash uchun fon ilovalarini o‘ldirishi mumkin. largeHeap ni faqat obʼektiv ravishda ko‘p xotiraga muhtoj ilovalar uchun ishlating (kameralar, muharrirlar).
OOM — Heap yetishmasligida ilova ichidagi istisno. Tizim tomonidan o‘ldirish (Low Memory Killer) — boshqa ilovalar uchun xotirani bo‘shatish maqsadida Linux yadrosining jarayonni o‘ldirish qarori. Tizim tomonidan o‘ldirishda ilova istisno olmaydi — jarayon shunchaki tugaydi.
Formula: width × height × bytesPerPixel. ARGB_8888 = 4 B/piksel, RGB_565 = 2 B/piksel. ARGB_8888 da FullHD Bitmap (1920 × 1080) = 8.3 MB. 4K Bitmap (3840 × 2160) = 33 MB. Tasvirlarni har doim ekranda ko‘rsatish uchun zarur bo‘lgan o‘lchamga masshtablang.
Xulosa
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.