OutOfMemoryError sa pag-develop ng aplikasyon: ano ito, mga sanhi at paraan ng pag-iwas

May-akda: IT Sectr Nai-publish: 2026-03-29 Oras ng pagbabasa: 9 min

OutOfMemoryError — isang nakamamatay na exception na nangyayari kapag ang Java Virtual Machine (JVM) o Android Runtime (ART) ay hindi maka-allocate ng memory para sa isang bagong object dahil sa kakulangan ng espasyo sa Heap. Ayon sa Square Engineering, 70% ng OutOfMemoryError sa mga mobile application ay sanhi ng memory leaks, hindi aktwal na paglampas sa limitasyon. Pag-unawa sa mga sanhi ng OOM ay susi sa matatag na paggana ng aplikasyon.

Mga Pangunahing Punto

  • OutOfMemoryError — exception kapag walang sapat na Heap para sa bagong object
  • Heap (tambak) — lugar ng memorya kung saan naninirahan ang lahat ng Java/Kotlin object
  • Bitmap — pangunahing gumagamit ng Heap sa Android, karaniwang pinagmumulan ng OOM
  • Heap Dump — snapshot ng tambak para sa pagsusuri kung sino ang gumagamit ng memorya
  • Paggamot sa OOM ay nangangailangan ng pag-aayos ng leaks at pag-optimize ng paggamit ng memorya

Ano ang OutOfMemoryError

OutOfMemoryError (OOM) — isang exception mula sa pamilyang VirtualMachineError sa Java/Kotlin na nagpapahiwatig ng kawalan ng kakayahang mag-allocate ng memory para sa isang bagong object. Hindi tulad ng checked exceptions, ang OOM ay isang Error at hindi nangangailangan ng paghawak sa pamamagitan ng catch — kahit na teknikal na posibleng mahuli ito. Pagkatapos ng OOM, ang aplikasyon ay karaniwang nasa hindi matatag na estado at inirerekomenda na isara ito.

Sa Android, bawat aplikasyon ay may limitasyon ng Heap na itinakda ng gumawa ng device. Para sa mga modernong smartphone na may 6+ GB RAM, ang limitasyon ay 256–512 MB, para sa mga budget device — 128–192 MB. Kapag ang kabuuang dami ng lahat ng buhay na object ay lumampas sa limitasyong ito, ang ART ay nagtatapon ng OutOfMemoryError.

Mahalaga na maunawaan: ang OOM ay hindi palaging nangangahulugan na ang pisikal na memorya ng device ay naubos. Ito ay nangangahulugan na ang aplikasyon ay naubos na ang limitasyon ng Heap na itinakda ng system. Ang ibang mga aplikasyon ay maaaring may libreng memorya, ngunit ang iyong aplikasyon ay hindi ito magagamit dahil sa paghihiwalay ng proseso sa Android.

Mga Pangunahing Sanhi ng OutOfMemoryError

Limang senaryo ang regular na humahantong sa OOM sa mga mobile application. Bawat senaryo ay nauugnay sa isang partikular na uri ng data o operasyon.

Bitmap nang walang scaling

Bitmap — pangunahing gumagamit ng memorya sa mga Android application. Ang pag-load ng FullHD na imahe (1920 × 1080) sa orihinal na laki ay kumukuha ng 8.3 MB sa ARGB_8888 format. Kung may 50 ganoong imahe sa RecyclerView — iyon ay 415 MB, na lumalampas sa Heap ng anumang device. Ang pag-load ng mga imahe nang walang inSampleSize — garantisadong OOM sa mahinang mga device.

Gumamit ng Glide o Coil para sa awtomatikong scaling. Ang mga library na ito ay naglo-load ng mga imahe sa laki na naaayon sa View, hindi sa orihinal na resolution. Para sa direktang paggamit ng BitmapFactory.Options, ilapat ang inSampleSize: kalkulahin ito bilang kapangyarihan ng dalawa upang ang huling laki ay hindi lalampas sa 2048 × 2048 pixels. Dagdag pa, gamitin ang RGB_565 sa halip na ARGB_8888 para sa mga imaheng walang transparency — ito ay nagbabawas ng konsumo ng memorya ng kalahati.

kotlin
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)
}

Mga memory leak (akumulasyon)

Isang leak ng ilang KB ay hindi magiging sanhi ng OOM. Ngunit dose-dosenang leaks sa bawat screen ay naipon: bawat transition sa isang screen ay nagdaragdag ng leak, hindi mapalaya ng GC ang mga object, napupuno ang Heap. Karaniwang pattern: binubuksan at isinasara ng user ang profile screen nang 20 beses → ang Heap ay lumalaki ng 200 MB → ang aplikasyon ay nag-crash na may OOM.

I-install ang LeakCanary sa proyekto para sa awtomatikong pag-detect ng leaks. Ito ay magpapakita ng bawat tumutulong object na may tumpak na stack trace. Pagkatapos ayusin ang lahat ng leaks, ang konsumo ng Heap ay magiging matatag: pagkatapos isara ang screen, ang memorya ay babalik sa batayang antas.

Malalaking file sa memorya

Pag-load ng mga file nang buo sa byte[] — direktang daan patungo sa OOM. Ang isang JSON file na 50 MB sa pag-parse ay lilikha ng string ng parehong laki kasama ang DOM model. Ang mga video file na na-load sa memorya, audio buffer, at malalaking protobuf dataset — lahat ay maaaring lumampas sa limitasyon ng Heap sa isang operasyon.

Iproseso ang malalaking data gamit ang stream: InputStream na may buffer na 4–8 KB, streaming JSON parser (Jackson o Gson na may JsonReader), MediaCodec para sa video. Huwag kailanman tawagan ang File.readBytes() sa mga file na mas malaki sa 10% ng available na Heap.

Paglikha ng maraming object sa loop

Masinsinang paglikha ng mga object sa loop na walang intervening GC ay maaaring humantong sa OOM, lalo na sa mga device na may maliit na Heap. Halimbawa: pag-generate ng 100,000 object sa for-loop na hindi kasya sa Heap bago pa man makolekta ng GC ang mga ito. Ito ay mas karaniwan sa mga laro at graphic editor.

Gumamit ng Object Pool para sa mga object na mass na nilikha at winawasak. Para sa numerical data, gumamit ng primitive types (FloatArray sa halip na List<Float>). Ang RecyclerView na may ViewHolder Pool ay lumulutas ng problemang ito para sa mga UI component.

Fragmentasyon ng Heap

Fragmentasyon — estado kung saan ang libreng memorya ay sapat sa kabuuan, ngunit walang tuloy-tuloy na bloke para sa bagong object. Ang ART ay nag-compact ng Heap sa panahon ng GC, ngunit hindi palaging matagumpay. Ang malalaking array (Bitmap, byte[]) ay pinaka-sensitive sa fragmentation.

Ang ART sa Android 8+ ay gumagamit ng Generational GC, na nagbabawas ng fragmentation sa pamamagitan ng paghihiwalay ng mga bata at matandang object. Gayunpaman, iwasan ang pag-allocate ng mga fragment na may iba’t ibang laki sa iisang pool — subukang gumamit ng pre-allocated buffer na may nakapirming laki.

Mga Limitasyon ng Heap sa Android

Ang limitasyon ng Heap sa Android ay hindi konstant — depende ito sa gumawa, modelo ng device, at bersyon ng OS. Ang Google ay nagtatakda ng mga minimum na kinakailangan sa pamamagitan ng Compatibility Definition Document (CDD), ngunit ang mga gumagawa ay nagtatakda ng aktwal na mga halaga.

Kategorya ng DeviceKaraniwang HeaplargeHeap
Budget (1–2 GB RAM)128–192 MB256–384 MB
Mid-range (3–4 GB RAM)256–384 MB512 MB
Flagship (6+ GB RAM)384–512 MB768 MB–1 GB
Tablet (4+ GB RAM)256–512 MB768 MB
Wear OS32–64 MBWala

Maaaring humiling ng mas mataas na limitasyon sa pamamagitan ng android:largeHeap="true" sa manifest. Gamitin ito nang maingat: ang pagtaas ng Heap ay hindi lumulutas ng problema ng leaks at maaaring magpababa ng karanasan ng user kung ang sistema ay mapipilitang patayin ang ibang mga aplikasyon upang magbakante ng memorya. Para sa Wear OS, ang limitasyon ng Heap ay minimal — 32–64 MB lamang, dito ang largeHeap ay hindi available, at ang pagtitipid ng memorya ay dobleng kritikal.

Diagnosis ng OutOfMemoryError

Diagnosis ng OOM ay nangangailangan ng pagsusuri ng Heap Dump at pag-unawa kung aling mga object ang kumokonsumo ng memorya. Ang Android Studio ay nagbibigay ng lahat ng kinakailangang kasangkapan.

Hakbang 1: Huwag ang OOM moment. Sa Android Memory Profiler, pindutin ang Record memory allocations at isagawa ang senaryo na nagdudulot ng crash. Ang profiler ay magpapakita ng pagtalon ng mga alokasyon bago ang OOM. Kung hindi ma-reproduce ang OOM, bawasan ang Heap sa pamamagitan ng android:smallHeap sa debug build o gumamit ng DDMS na may manu-manong tawag sa GC.

Hakbang 2: Kumuha ng Heap Dump sa oras ng peak load (bago ang OOM). Buksan ang Dump sa Android Studio: ang tab na Classes ay naayos ayon sa Retained Size. Ang pinakamalaking object — Bitmap, byte[], String. Para sa bawat Bitmap, suriin ang laki (width × height × 4 bytes) at ang landas ng pag-load sa pamamagitan ng Stack Trace.

Hakbang 3: Suriin ang bilang ng mga umuulit na object. Kung makakita ka ng 200 magkaparehong Fragment o Activity — iyon ay leak. Kung 500 Bitmap na may parehong laki — problema sa cache ng imahe. Ang MAT (Memory Analyzer Tool) ay nagbibigay ng mas malalim na pagsusuri na may Dominator Tree, na nagpapakita kung aling mga object ang may hawak ng 80% ng Heap.

text
// Utos para sa Heap Dump sa pamamagitan ng adb
adb shell am dumpheap com.example.app /data/local/tmp/dump.hprof
adb pull /data/local/tmp/dump.hprof.

Mga Estratehiya sa Pag-iwas ng OOM

Isang komprehensibong estratehiya sa pag-iwas ng OOM ay may limang antas ng proteksyon: mula sa mga solusyong arkitektural hanggang sa pag-monitor sa produksyon.

Mga Solusyong Arkitektural

ViewModel + Repository pattern ay naghihiwalay ng data mula sa UI at pumipigil sa paghawak ng View sa pag-ikot ng screen. Ang ViewModel ay nabubuhay nang mas mahaba kaysa sa Activity, ang data nito ay hindi nawawala, at ang View ay maaaring muling likhain nang walang pagdoble ng data sa memorya. Gumamit ng StateFlow sa halip na LiveData para sa malinaw na pamamahala ng estado.

Pamamahala ng Bitmap at mga Imahe

Glide — sapilitang library para sa pagtatrabaho sa mga imahe. Ito ay awtomatikong nag-scale, nag-cache (disk + memorya), at nagre-recycle ng Bitmap. I-configure ang diskCacheStrategy at skipMemoryCache para sa malalaking listahan. Para sa mga animated na imahe, gumamit ng Glide na may GIF/WebP — sila ay kumukuha ng mas kaunting memorya kaysa sa isang sequence ng Bitmap.

Pag-monitor sa Produksyon

Firebase Performance Monitoring ay sumusubaybay sa konsumo ng memorya sa real-time. Magtakda ng alert sa paggamit ng Heap na higit sa 80% ng limitasyon — ito ay senyales para sa pagsusuri. Ang Crashlytics ay nagtitipon ng OOM bilang exception at nagpapakita ng huling kilalang estado ng Heap bago ang crash. Para sa Android 11+, gamitin ang ApplicationExitInfo para sa detection ng OOM termination.

Pagsubok sa Mahinang mga Device

Sapilitang subukan ang aplikasyon sa mga device na may pinakamababang Heap (128–192 MB). Ang emulator na may maliit na screen at maliit na Heap ay ginagaya ang isang budget device. Kung ang aplikasyon ay gumagana sa naturang device, sa mga flagship ay walang magiging problema sa OOM. Gamitin ang Firebase Test Lab na may mga tunay na device mula sa iba’t ibang kategorya ng presyo.

kotlin
// Pagsusuri ng available na Heap bago ang mabigat na operasyon
fun canAllocate(requiredBytes: Long): Boolean {
    val runtime = Runtime.getRuntime()
    val free = runtime.freeMemory()
    return free > requiredBytes * 2 // reserba 50%
}

Mga Madalas Itanong

Maaari bang mahuli ang OutOfMemoryError sa pamamagitan ng try-catch?

Teknikal na oo, ngunit hindi ito inirerekomenda. Pagkatapos ng OOM, ang aplikasyon ay nasa hindi matatag na estado: ang mga bagong alokasyon ay maaaring hindi gumana, at ang ilang mga object ay maaaring bahagyang nalikha. Ang tanging makatwirang aksyon sa catch — pag-log at pag-restart ng Activity.

Bakit hindi nangyayari ang OOM sa lahat ng device?

Ang limitasyon ng Heap ay iba sa iba’t ibang device. Ang operasyon na nangangailangan ng 300 MB ay babagsak sa device na may limitasyon na 192 MB, ngunit gagana sa flagship na may 512 MB. Subukan sa mga device na may pinakamababang specs upang matuklasan ang mga OOM scenario.

Paano nakakaapekto ang largeHeap sa pagganap?

largeHeap ay nagtataas ng limitasyon, ngunit hindi pinapabilis ang aplikasyon. Ang mga paghinto ng GC ay nagiging mas mahaba dahil ang pag-ipon ng malaking Heap ay mas matagal. Ang sistema ay maaaring pumatay ng mga background application upang magbigay ng memorya. Gamitin ang largeHeap lamang para sa mga aplikasyon na talagang nangangailangan ng maraming memorya (mga camera, editor).

Ano ang pagkakaiba ng OOM sa pagpatay ng proseso ng system?

OOM — exception sa loob ng aplikasyon kapag kulang ang Heap. Ang pagpatay ng system (Low Memory Killer) — desisyon ng Linux kernel na pumatay ng proseso upang magbakante ng memorya para sa ibang mga aplikasyon. Sa pagpatay ng system, ang aplikasyon ay hindi tumatanggap ng exception — ang proseso ay nagtatapos lamang.

Gaano karaming memorya ang aktwal na ginagamit ng Bitmap?

Formula: width × height × bytesPerPixel. ARGB_8888 = 4 B/pixel, RGB_565 = 2 B/pixel. FullHD Bitmap (1920 × 1080) sa ARGB_8888 = 8.3 MB. 4K Bitmap (3840 × 2160) = 33 MB. Palaging i-scale ang mga imahe sa laki na kinakailangan para sa pagpapakita sa screen.

Buod

  • OutOfMemoryError — nakamamatay na exception kapag naubos ang limitasyon ng Heap ng aplikasyon
  • Bitmap nang walang scaling — pangunahing sanhi ng OOM sa mga mobile application
  • Mga memory leak ay nagdudulot ng 70% ng OOM sa pamamagitan ng akumulasyon ng object sa bawat nabigasyon
  • Limitasyon ng Heap ay nag-iiba mula 128 MB sa budget device hanggang 512 MB sa flagship
  • Heap Dump na may pagsusuri ng Retained Size — pangunahing kasangkapan sa diagnosis ng OOM
  • Glide o Coil ay sapilitan para sa pagtatrabaho sa mga imahe ng anumang laki
  • Pagsubok sa mga device na may pinakamababang Heap — must-have para sa lahat ng proyekto

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din