OutOfMemoryError az alkalmazásfejlesztésben: mi ez, okai és megelőzési módszerek

Szerző: IT Sectr Megjelenés: 2026-03-29 Olvasási idő: 9 perc

OutOfMemoryError — egy végzetes kivétel, amely akkor keletkezik, amikor a Java Virtual Machine (JVM) vagy Android Runtime (ART) nem tud memóriát foglalni egy új objektum számára a Heap-ben lévő hely hiánya miatt. A Square Engineering szerint a mobilalkalmazásokban előforduló OutOfMemoryError-ok 70%-át memóriaszivárgások okozzák, nem a tényleges határtúllépés. Az OOM okainak megértése a kulcs az alkalmazás stabil működéséhez.

Főbb pontok

  • OutOfMemoryError — kivétel, ha nincs elég Heap egy új objektum létrehozásához
  • Heap (halom) — a memóriaterület, ahol az összes Java/Kotlin objektum él
  • Bitmap — a Heap fő fogyasztója Androidon, tipikus OOM-forrás
  • Heap Dump — a halom pillanatképe annak elemzéséhez, ki mennyi memóriát használ
  • OOM kezelése a szivárgások megszüntetését és a memóriahasználat optimalizálását igényli

Mi az OutOfMemoryError

OutOfMemoryError (OOM) — a VirtualMachineError családjába tartozó kivétel Java/Kotlin nyelven, amely azt jelzi, hogy nem lehet memóriát foglalni egy új objektum számára. A checked kivételekkel ellentétben az OOM egy Error, és nem igényel catch-en keresztüli kezelést — bár technikailag elkapható. Az OOM fellépése után az alkalmazás általában instabil állapotban van, és javasolt bezárni.

Androidon minden alkalmazásnak van az eszköz gyártója által beállított Heap-korlátja. A 6+ GB RAM-mal rendelkező modern okostelefonok esetében a korlát 256–512 MB, az olcsóbb eszközök esetében — 128–192 MB. Amikor az összes élő objektum össztérfogata meghaladja ezt a korlátot, az ART OutOfMemoryError-t dob.

Fontos megérteni: az OOM nem mindig jelenti azt, hogy az eszköz fizikai memóriája elfogyott. Azt jelenti, hogy az alkalmazás kimerítette a rendszer által beállított Heap-korlátját. Más alkalmazásoknak lehet szabad memóriájuk, de az Ön alkalmazása nem használhatja azt az Android folyamatizolációja miatt.

Az OutOfMemoryError fő okai

Öt forgatókönyv vezet rendszeresen OOM-hoz mobilalkalmazásokban. Minden forgatókönyv egy adott adattípushoz vagy művelethez kapcsolódik.

Bitmap méretezés nélkül

Bitmap — a fő memóriafogyasztó Android-alkalmazásokban. Egy FullHD kép (1920 × 1080) betöltése eredeti méretben 8.3 MB-ot foglal ARGB_8888 formátumban. Ha 50 ilyen kép van egy RecyclerView-ban — az 415 MB, ami meghaladja bármely eszköz Heap-jét. Képek betöltése inSampleSize nélkül — garantált OOM gyenge eszközökön.

Használjon Glide-ot vagy Coil-t az automatikus méretezéshez. Ezek a könyvtárak a View-hoz igazított méretben töltik be a képeket, nem az eredeti felbontásban. A BitmapFactory.Options közvetlen használatához alkalmazza az inSampleSize-t: számítsa ki két hatványaként úgy, hogy a végső méret ne haladja meg a 2048 × 2048 pixelt. Ezenkívül átlátszóság nélküli képekhez használjon RGB_565-öt ARGB_8888 helyett — ez felezi a memóriafogyasztást.

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

Memóriaszivárgások (felhalmozódás)

Egy pár KB-os szivárgás nem okoz OOM-ot. De tucatnyi szivárgás minden képernyőn felhalmozódik: minden átmenet egy képernyőre hozzáad egy szivárgást, a GC nem tudja felszabadítani az objektumokat, a Heap megtelik. Tipikus mintázat: a felhasználó 20-szor nyitja meg és zárja be a profil képernyőt → a Heap 200 MB-tal nő → az alkalmazás OOM-mal összeomlik.

Telepítse a LeakCanary-t a projektbe az automatikus szivárgásészleléshez. Ez minden kiszivárgott objektumot megjelenít a pontos stack trace-szel. Az összes szivárgás kijavítása után a Heap használata stabillá válik: a képernyő bezárása után a memória visszatér az alapszintre.

Nagyméretű fájlok a memóriában

Fájlok teljes egészében byte[]-ba töltése — közvetlen út az OOM-hoz. Egy 50 MB-os JSON fájl elemzéskor egy ugyanolyan méretű stringet és DOM modellt hoz létre. A memóriába töltött videofájlok, audio puffer és nagy protobuf adathalmazok — mindegyik túllépheti a Heap korlátot egyetlen művelettel.

Dolgozza fel a nagy adatokat folyamokkal: InputStream 4–8 KB pufferrel, streaming JSON parser (Jackson vagy Gson JsonReader-rel), MediaCodec videóhoz. Soha ne hívja a File.readBytes() metódust a rendelkezésre álló Heap 10%-nál nagyobb fájlokon.

Számos objektum létrehozása ciklusban

Intenzív objektumlétrehozás ciklusban köztes GC nélkül OOM-hoz vezethet, különösen kis Heap-pel rendelkező eszközökön. Példa: 100.000 objektum generálása egy for ciklusban, amelyek nem férnek el a Heap-ben, mielőtt a GC össze tudná gyűjteni őket. Ez gyakoribb játékokban és grafikus szerkesztőkben.

Használjon Object Pool-t azokhoz az objektumokhoz, amelyeket tömegesen hoz létre és semmisít meg. Numerikus adatokhoz használjon primitív típusokat (FloatArray a List<Float> helyett). A RecyclerView ViewHolder Pool-lal megoldja ezt a problémát az UI komponensek számára.

Heap fragmentáció

Fragmentáció — állapot, amikor összességében elegendő szabad memória van, de nincs folytonos blokk egy új objektum számára. Az ART a GC során tömöríti a Heap-et, de nem mindig sikeresen. A nagyméretű tömbök (Bitmap, byte[]) a legérzékenyebbek a fragmentációra.

Az ART Android 8+-on Generational GC-t használ, amely a fiatal és öreg objektumok szétválasztásával csökkenti a fragmentációt. Ennek ellenére kerülje a különböző méretű fragmensek egy medencében történő lefoglalását — próbáljon előre lefoglalt, rögzített méretű puffereket használni.

Heap-korlátok Androidon

A Heap korlát Androidon nem állandó — függ a gyártótól, az eszköz modelljétől és az OS verziójától. A Google a Compatibility Definition Document (CDD) segítségével határozza meg a minimális követelményeket, de a gyártók állítják be a tényleges értékeket.

EszközkategóriaTipikus HeaplargeHeap
Olcsó (1–2 GB RAM)128–192 MB256–384 MB
Közepes (3–4 GB RAM)256–384 MB512 MB
Csúcs (6+ GB RAM)384–512 MB768 MB–1 GB
Tabletek (4+ GB RAM)256–512 MB768 MB
Wear OS32–64 MBNincs

Növelt korlátot kérhet az android:largeHeap="true" segítségével a manifesztumban. Használja óvatosan: a Heap növelése nem oldja meg a szivárgási problémát, és ronthatja a felhasználói élményt, ha a rendszer kényszerül más alkalmazásokat leállítani a memória felszabadítása érdekében. Wear OS esetén a Heap korlát minimális — mindössze 32–64 MB, itt a largeHeap nem érhető el, és a memóriamegtakarítás kétszeresen kritikus.

OutOfMemoryError diagnosztizálása

Az OOM diagnosztizálása Heap Dump elemzést és annak megértését igényli, hogy mely objektumok fogyasztanak memóriát. Az Android Studio minden szükséges eszközt biztosít.

1. lépés: Fogja el az OOM pillanatát. Az Android Memory Profilerben nyomja meg a Record memory allocations gombot, és hajtsa végre az összeomlást okozó forgatókönyvet. A profiler megmutatja az allokációk ugrását az OOM előtt. Ha az OOM nem reprodukálható, csökkentse a Heap-et az android:smallHeap segítségével debug építésben, vagy használja a DDMS-t kézi GC-hívással.

2. lépés: Készítsen Heap Dump-ot a csúcs terhelés pillanatában (az OOM előtt). Nyissa meg a Dump-ot az Android Studio-ban: a Classes fül a Retained Size szerint van rendezve. A legnagyobb objektumok — Bitmap, byte[], String. Minden Bitmap esetében ellenőrizze a méretet (width × height × 4 bájt) és a betöltési útvonalat a Stack Trace-en keresztül.

3. lépés: Elemezze az ismétlődő objektumok számát. Ha 200 azonos Fragmentet vagy Activity-t lát — az szivárgás. Ha 500 azonos méretű Bitmap — képgyorsítótár-probléma. A MAT (Memory Analyzer Tool) mélyebb elemzést biztosít Dominator Tree-vel, megmutatva, hogy mely objektumok tartják a Heap 80%-t.

text
// Parancs a Heap Dump-hoz adb-n keresztül
adb shell am dumpheap com.example.app /data/local/tmp/dump.hprof
adb pull /data/local/tmp/dump.hprof.

OOM megelőzési stratégiák

Egy átfogó OOM-megelőzési stratégia öt védelmi szintet foglal magában: az architekturális megoldásoktól a éles célú monitorozásig.

Architekturális megoldások

ViewModel + Repository minta elkülöníti az adatokat az UI-tól, és megakadályozza a View megtartását képernyő forgatásakor. A ViewModel túlléli az Activity-t, adatai nem vesznek el, és a View újra létrehozható anélkül, hogy az adatok megkettőződénének a memóriában. Használjon StateFlow-t a LiveData helyett az állapotok explicit kezeléséhez.

Bitmap és képkezelés

Glide — kötelező könyvtár a képekkel való munkához. Automatikusan méretez, gyorsítótáraz (lemez + memória) és újrahasznosítja a Bitmap-et. Konfigurálja a diskCacheStrategy és skipMemoryCache beállításokat nagy listákhoz. Animált képekhez használja a Glide-ot GIF/WebP-vel — ezek kevesebb memóriát foglalnak, mint a Bitmap sorozatok.

Éles célú monitorozás

Firebase Performance Monitoring valós időben követi a memóriafogyasztást. Állítson be riasztást, ha a Heap több mint 80%-ban használt — ez egy ellenőrzési jel. A Crashlytics OOM-ot kivételként gyűjti, és megmutatja az utolsó ismert Heap állapotot az összeomlás előtt. Android 11+ esetén használja az ApplicationExitInfo-t az OOM-befejezések észleléséhez.

Tesztelés gyenge eszközökön

Kötelezően tesztelje az alkalmazást minimális Heap-pel (128–192 MB) rendelkező eszközökön. A kis képernyős és kis Heap-pel rendelkező emulátor egy olcsó eszközt szimulál. Ha az alkalmazás működik egy ilyen eszközön, a csúcseszközökön nem lesz OOM-probléma. Használja a Firebase Test Lab-ot különböző árkategóriájú valós eszközökkel.

kotlin
// Rendelkezésre álló Heap ellenőrzése nehéz művelet előtt
fun canAllocate(requiredBytes: Long): Boolean {
    val runtime = Runtime.getRuntime()
    val free = runtime.freeMemory()
    return free > requiredBytes * 2 // 50% tartalék
}

Gyakran Ismételt Kérdések

Elkapható az OutOfMemoryError try-catch segítségével?

Technikailag igen, de nem ajánlott. OOM után az alkalmazás instabil állapotban van: az új allokációk nem működhetnek, és egyes objektumok részben létrehozottak lehetnek. Az egyetlen ésszerű művelet a catch-ben — naplózás és az Activity újraindítása.

Miért nem történik OOM minden eszközön?

A Heap korlát különböző a különböző eszközökön. Egy 300 MB-ot igénylő művelet összeomlik egy 192 MB korlátú eszközön, de működik egy 512 MB-os csúcseszközön. Teszteljen minimális specifikációjú eszközökön az OOM-forgatókönyvek felfedezéséhez.

Hogyan befolyásolja a largeHeap a teljesítményt?

largeHeap növeli a korlátot, de nem gyorsítja fel az alkalmazást. A GC szünetek hosszabbak lesznek, mert a nagy Heap összegyűjtése több ideig tart. A rendszer leállíthat hättéralkalmazásokat a memória biztosítása érdekében. Használja a largeHeap-ot csak azokhoz az alkalmazásokhoz, amelyek objektíven sok memóriát igényelnek (kamerák, szerkesztők).

Miben különbözik az OOM a rendszer általi folyamatgyilkosságtól?

OOM — kivétel az alkalmazáson belül, ha nincs elég Heap. A rendszer általi gyilkosság (Low Memory Killer) — a Linux kernel döntése, hogy megöl egy folyamatot a memória felszabadítása érdekében más alkalmazások számára. Rendszer általi gyilkosságnál az alkalmazás nem kap kivételt — a folyamat egyszerűen véget ér.

Mennyi memóriát foglal ténylegesen egy Bitmap?

Képlet: width × height × bytesPerPixel. ARGB_8888 = 4 B/pixel, RGB_565 = 2 B/pixel. FullHD Bitmap (1920 × 1080) ARGB_8888-ban = 8.3 MB. 4K Bitmap (3840 × 2160) = 33 MB. Mindig méretezze át a képeket a képernyőn történő megjelenítéshez szükséges méretre.

Összefoglaló

  • OutOfMemoryError — végzetes kivétel az alkalmazás Heap korlátjának kimerülésekor
  • Bitmap méretezés nélkül — az OOM fő okos mobilalkalmazásokban
  • Memóriaszivárgások az OOM-ok 70%-t okozzák az objektumok felhalmozódásával minden navigációnál
  • Heap korlát 128 MB-tól (olcsó eszközök) 512 MB-ig (csúcs eszközök) terjed
  • Heap Dump Retained Size elemzéssel — az OOM diagnosztika fő eszköze
  • Glide vagy Coil kötelező a bármilyen méretű képekkel való munkához
  • Tesztelés minimális Heap-pel rendelkező eszközökön — must-have minden projekthez

Kulcsrakész mobilalkalmazást fejlesztünk

Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.

Projekt megbeszélése

Olvassa el is