A Memory Profiler az Android Profiler egyik összetevője, amely segít azonosítani a memóriaszivárgásokat és a memóriakeresést, amelyek dadogáshoz, lefagyáshoz és akár az alkalmazás összeomlásához is vezethetnek. Valós idejű grafikonon mutatja az alkalmazás memóriahasználatát, és lehetővé teszi a heap dump rögzítését, a szemétgyűjtés kikényszerítését és a memóriafoglalások nyomon követését.
A Memóriaprofilozó megnyitásához kövesse a következő lépéseket:
- Kattintson a Nézet > Eszközablakok > Profilozó (az eszköztáron a Profil gombra is kattinthat).
- Az AndroidProfiler eszköztáron válassza ki a profilozni kívánt eszközt és alkalmazásfolyamatot. Ha USB-n keresztül csatlakoztatott egy eszközt, de nem látja a listában, győződjön meg róla, hogy bekapcsolta az USB hibakeresést.
- Kattintson bárhol a MEMORY idővonalra a Memory Profiler megnyitásához.
Alternatívaként megvizsgálhatja az alkalmazás memóriáját a parancssorból withdumpsys, és a GC eseményeket is megtekintheti a logcat-ben.
Miért érdemes profilozni az alkalmazás memóriáját
Android egy felügyelt memóriakörnyezetet biztosít – amikor megállapítja, hogy az alkalmazás már nem használ bizonyos objektumokat, a szemétgyűjtő visszaadja a nem használt memóriát a kupacnak. Azt, hogy az Android hogyan találja meg a fel nem használt memóriát, folyamatosan fejlesztik, de egy bizonyos ponton minden Androidverzióban a rendszernek rövid időre szüneteltetnie kell a kódot. A szünetek legtöbbször észrevehetetlenek. Ha azonban az alkalmazás gyorsabban osztja ki a memóriát, mint ahogy a rendszer képes összegyűjteni azt, az alkalmazás késhet, amíg a gyűjtő elegendő memóriát szabadít fel a kiosztások kielégítéséhez. A késedelem miatt az alkalmazás kihagyhat kereteket, és látható lassúságot okozhat.
Még ha az alkalmazás nem is mutat lassúságot, ha memóriát szivárogtat, akkor is megtarthatja a memóriát, amíg a háttérben van. Ez a viselkedés lelassíthatja a rendszer memóriateljesítményének többi részét, mivel szükségtelen szemétgyűjtési eseményeket kényszerít ki. Végül a rendszer kénytelen megölni az alkalmazás folyamatát, hogy visszaszerezze a memóriát. Ezután, amikor a felhasználó visszatér az alkalmazásához, annak teljesen újra kell indulnia.
Az ilyen problémák megelőzése érdekében a Memory Profiler segítségével a következőket kell tennie:
- Nemkívánatos memóriaelosztási mintákat keres az idővonalban, amelyek teljesítményproblémákat okozhatnak.
- Dumpolja a Java heapet, hogy lássa, mely objektumok használják a memóriát egy adott időpontban. Több heap-dömping hosszabb időn keresztül segíthet a memóriaszivárgások azonosításában.
- Rögzítse a memóriafoglalásokat normál és extrém felhasználói interakciók során, hogy pontosan azonosítani tudja, hogy a kódja rövid idő alatt túl sok objektumot foglal le, vagy olyan objektumokat foglal le, amelyek szivárognak.
Az alkalmazás memóriahasználatát csökkentő programozási gyakorlatokról szóló információkért olvassa el a Manage your app’s memory.
Memory Profiler overview
A Memory Profiler első megnyitásakor részletes idővonal látható az alkalmazás memóriahasználatáról, és hozzáférhet a szemétgyűjtés kikényszerítésére, a heapdump rögzítésére és a memóriafoglalások rögzítésére szolgáló eszközökhöz.
1. ábra. A Memory Profiler
Az 1. ábrán látható módon a Memory Profiler alapértelmezett nézete a következőket tartalmazza:
- A garbage collection esemény kikényszerítésére szolgáló gomb.
-
A heap dump rögzítésére szolgáló gomb.
Megjegyzés: A memóriafoglalások rögzítésére szolgáló gomb csak akkor jelenik meg a heap dump gomb jobb oldalán, ha Android 7.1 (25-ös API-szint) vagy alacsonyabb szintű Android 7.1-et futtató eszközhöz csatlakozik.
- Egy legördülő menü, amellyel megadható, hogy a profilozó milyen gyakran rögzítse a memóriafoglalásokat. A megfelelő opció kiválasztása segíthet javítani az alkalmazás teljesítményét profilozás közben.
- Gombok az idővonal nagyításához/ kicsinyítéséhez.
- Egy gomb az élő memóriaadatokra való előreugráshoz.
- Az eseményidővonal, amely a tevékenységállapotokat, a felhasználói beviteli eseményeket és a képernyőforgatási eseményeket mutatja.
- A memóriahasználati idővonal, amely a következőket tartalmazza:
- Egy egymásra helyezett grafikon, amely azt mutatja, hogy az egyes memóriakategóriák mennyi memóriát használnak, amint azt a bal oldali y-tengely és a felső színkulcs jelzi.
- Egy szaggatott vonal jelzi az allokált objektumok számát, amint azt a jobb oldali y-tengely mutatja.
- Egy ikon minden egyes szemétgyűjtési eseményhez.
Ha azonban Android 7.1 vagy alacsonyabb verziószámú készüléket használ, alapértelmezés szerint nem minden profilozási adat látható. Ha a következő üzenetet látja: “A speciális profilkészítés nem elérhető a kiválasztott folyamathoz”, akkor engedélyeznie kell a speciális profilkészítést, hogy láthassa a következőket:
- Esemény idővonal
- A kiosztott objektumok száma
- Szemétgyűjtési események
Az Android 8.0 és újabb rendszerekben a fejlett profilkészítés mindig engedélyezve van a debuggolható alkalmazásoknál.
Hogyan számolják a memóriát
A memóriaprofilozó tetején látható számok (2. ábra) azAndroid rendszere szerint az alkalmazás által lekötött összes privát memóriaoldalon alapulnak. Ez a számlálás nem tartalmazza a rendszerrel vagy más alkalmazásokkal megosztott oldalakat.
2. ábra. A memóriaszámlálás legendája a Memory Profiler tetején
A memóriaszámlálás kategóriái a következők:
- Java: Java vagy Kotlin kódból allokált objektumokból származó memória.
-
Natív: C vagy C++ kódból kiosztott objektumokból származó memória.
Még ha nem is használ C++-t az alkalmazásában, akkor is láthat itt némi natív memória felhasználást, mivel az Android keretrendszer natív memóriát használ különböző feladatok elvégzésére az Ön nevében, például a képi eszközök és egyéb grafikák kezelésénél – még akkor is, ha a kódot Java vagy Kotlin nyelven írta.
-
Grafika: A pixelek képernyőre történő megjelenítéséhez használt grafikus puffervárakhoz használt memória, beleértve a GL felületeket, GL textúrákat és így tovább. (Megjegyzendő, hogy ez a CPU-val megosztott memória, nem dedikált GPU-memória.)
-
Stack: Az alkalmazásban a natív és a Java stackek által használt memória. Ez általában azzal függ össze, hogy hány szál fut az alkalmazásodban.
-
Code: Az alkalmazás által kódhoz és erőforrásokhoz használt memória, például dex bytecode, optimalizált vagy lefordított dex kód, .so könyvtárak és betűtípusok.
-
Más: Az alkalmazás által használt memória, amelyet a rendszer nem tudja pontosan kategorizálni.
-
Allokált: Az alkalmazás által allokált Java/Kotlin objektumok száma. Ez nem számolja a C vagy C++ nyelven kiosztott objektumokat.
Az Android 7.1-et vagy alacsonyabb verziószámú Androidot futtató készülékhez csatlakoztatva ez az allokációszámlálás csak akkor kezdődik, amikor a Memory Profiler csatlakozik a futó alkalmazásához. Tehát a profilkészítés megkezdése előtt kiosztott objektumokat nem veszi figyelembe. Az Android 8.0 és újabb verziók azonban tartalmaznak egy olyan eszközön belüli profilkészítő eszközt, amely nyomon követi az összes allokációt, így ez a szám mindig az Android 8.0 és újabb verziókon az alkalmazásban fennálló Java-objektumok teljes számát jelenti.
A korábbi Android Monitor eszköz memóriaszámlálásával összehasonlítva az újMemory Profiler másként rögzíti a memóriát, így úgy tűnhet, hogy a memóriahasználat most magasabb. A Memory Profiler megfigyel néhány extra kategóriát, amelyek növelik az összértéket, de ha csak a Java heap memóriája érdekli, akkor a “Java” számnak hasonlónak kell lennie az előző eszköz értékéhez.Bár a Java szám valószínűleg nem pontosan megegyezik azzal, amit az AndroidMonitorban látott, az új szám figyelembe veszi az összes fizikai memóriaoldalt, amelyet az alkalmazás Java heapjébe allokáltak, mióta az a Zygote-ból forkolták. Így ez pontos képet ad arról, hogy mennyi fizikai memóriát használ valójában az alkalmazás.
Memóriafoglalások megtekintése
A memóriafoglalások megmutatják, hogy az egyes Java-objektumok és JNI-hivatkozások hogyan lettek kiosztva a memóriában. Konkrétan a Memory Profiler a következőket tudja megmutatni az objektumkiosztásokról:
- Milyen típusú objektumok lettek kiosztva és mennyi helyet használnak.
- A stack trace minden kiosztásról, beleértve azt is, hogy melyik szálban.
- Az objektumok kiosztásának megszüntetésének időpontja (csak Android 8.0 vagy magasabb verziószámú eszköz használata esetén).
Ha a készüléken Android 8.0 vagy magasabb verziószámú rendszer fut, az objektumkiosztásokat bármikor megtekintheti az alábbiak szerint: Húzza az idővonalon, hogy kijelölje azt a területet, amelyre vonatkozóan meg szeretné tekinteni a kiosztásokat (az 1. videón látható módon). Nem szükséges felvételi munkamenetet indítani, mivel az Android 8.0 és újabb verziók tartalmaznak egy készüléken kívüli profilkészítő eszközt, amely folyamatosan nyomon követi az alkalmazás allokációit.
1. videó. Android 8.0 és újabb operációs rendszer esetén válasszon ki egy meglévő idővonalterületet az objektumkiosztások megtekintéséhez
Ha az eszközén Android 7.1 vagy alacsonyabb verziószámú Android fut, kattintson a Memóriaprofilozó eszköztáron a Memóriafoglalások rögzítése gombra. Felvétel közben aMemory Profiler nyomon követi az alkalmazásban előforduló összes allokációt. Ha végzett,kattintson a felvétel leállítása (ugyanaz a gomb; lásd a 2. videót) gombra a kiosztások megtekintéséhez.
2. videó. Android 7.1 és alacsonyabb verziók esetén kifejezetten rögzítenie kell a memóriafoglalásokat
Az idővonal egy régiójának kijelölése után (vagy amikor befejezi a felvételi munkamenetet egy Android 7.1-et futtató eszközzel.1 vagy annál alacsonyabb), az idővonal alatt megjelenik az allokált objektumok listája, osztálynév szerint csoportosítva és kupacszámuk szerint rendezve.
Az allokációs rekord vizsgálatához kövesse a következő lépéseket:
- Böngéssze a listát, hogy megtalálja azokat az objektumokat, amelyek szokatlanul nagy kupacszámmal rendelkeznek, és amelyek esetleg kiszivárogtak. Az ismert osztályok könnyebb megtalálásához kattintson az Osztálynévoszlop fejlécére az ábécé szerinti rendezéshez. Ezután kattintson egy osztály nevére. A jobb oldalon megjelenik azInstance View ablaktábla, amely az adott osztály minden példányát megmutatja, ahogy a 3. ábrán látható.
- Alternatívaként gyorsan megtalálhatja az objektumokat a Filter gombra kattintva, vagy a Control+F (Macen Command+F) billentyűkombinációval, és az osztály vagy csomag nevének beírásával a keresőmezőbe. Módszer neve alapján is kereshet, ha a legördülő menüből kiválasztja azArrange by callstack lehetőséget. Ha reguláris kifejezéseket szeretne használni, jelölje be a Regex melletti négyzetet. Jelölje be aMatch case melletti négyzetet, ha a keresési lekérdezés nagy- és kisbetű-érzékeny.
- Az Instance View ablaktáblában kattintson egy példányra. Alul megjelenik a Call Stack lap, amely megmutatja, hogy az adott példányt hol és melyik szálban osztották ki.
- A Call Stack lapon kattintson a jobb gombbal bármelyik sorra, és válassza aJump to Source (Ugrás a forráshoz) lehetőséget a kód megnyitásához a szerkesztőben.
3. ábra. Az egyes allokált objektumok részletei megjelennek a jobb oldali példánynézetben
Az allokált objektumok listája feletti két menü segítségével kiválaszthatja, hogy melyik kupacot vizsgálja, és hogyan rendezze az adatokat.
A bal oldali menüből kiválaszthatja, hogy melyik kupacot vizsgálja:
- alapértelmezett kupac:
- képheap: A rendszerindítási kép, amely a rendszerindításkor előretöltött osztályokat tartalmazza. Az itt lévő allokációk garantáltan soha nem mozognak vagy mennek el.
- zygote heap: A copy-on-write heap, ahonnan egy alkalmazásfolyamat elágazik az Android rendszerben.
- app heap: Az elsődleges heap, amelyen az alkalmazás memóriát rendel.
- JNI heap: A heap, amely megmutatja, hogy a Java Native Interface (JNI)-referenciák hol kerülnek kiosztásra és felszabadításra.
A jobb oldali menüből kiválaszthatja, hogyan kívánja elrendezni a kiosztásokat:
- Rendezés osztályok szerint: Az összes allokációt osztálynév alapján csoportosítja. Ez az alapértelmezett.
- Rendezés csomagok szerint: Az összes allokációt a csomag neve alapján csoportosítja.
- Arrange by callstack: Csoportosítja az összes allokációt a megfelelő hívási verembe.
Az alkalmazás teljesítményének javítása profilozás közben
Az alkalmazás teljesítményének javítása érdekében profilozás közben a memóriaprofilozó alapértelmezés szerint rendszeresen mintát vesz a memóriaallokációkból. A 26-os vagy magasabb API-szintű eszközökön végzett tesztelés során ezt a viselkedést megváltoztathatja a Allocation Tracking (Kiosztáskövetés) legördülő menüpont használatával. A rendelkezésre álló beállítások a következők:
- Teljes: Az összes objektumfoglalást rögzíti a memóriában. Ez az alapértelmezett viselkedés az Android Studio 3.2 és korábbi verziókban. Ha olyan alkalmazásod van, amely sok objektumot allokál, akkor profilozás közben látható lassulást tapasztalhatsz az alkalmazásodnál.
- Sampled: Rendszeres időközönként mintavételezi az objektumfoglalásokat a memóriában. Ez az alapértelmezett beállítás, és kevésbé befolyásolja az alkalmazás teljesítményét profilozás közben. Az olyan alkalmazások, amelyek rövid idő alatt sok objektumot allokálnak, mégis látható lassulást mutathatnak.
- Off: Leállítja az alkalmazás memóriaallokációjának nyomon követését.
Globális JNI-hivatkozások megtekintése
A Java Native Interface (JNI) egy olyan keretrendszer, amely lehetővé teszi, hogy a Java-kód és a natív kód hívja egymást.
A JNI-hivatkozásokat a natív kód manuálisan kezeli, így lehetséges, hogy a natív kód által használt Java-objektumok túl sokáig maradnak életben. Néhány objektum a Java-halomban elérhetetlenné válhat, ha egy JNI-hivatkozás elvetésre kerül anélkül, hogy előbb kifejezetten törölték volna. Az is lehetséges, hogy a globális JNI-hivatkozási korlát kimerül.
Az ilyen problémák elhárításához használja a Memory Profiler JNI heap nézetét az összes globális JNI-hivatkozás böngészéséhez, és szűrje őket Java-típusok és natív híváscsomagok szerint. Ezen információk segítségével megtudhatja, hogy mikor és hol jönnek létre és hol törlődnek a globális JNI-hivatkozások.
Az alkalmazás futása közben válassza ki az idővonal azon részét, amelyet meg akar vizsgálni, és válassza a JNI heap opciót az osztálylista feletti legördülő menüből.Ezután a szokásos módon megvizsgálhatja a halomban lévő objektumokat, és duplán kattinthat az Allocation Call Stack lapon lévő objektumokra, hogy megnézze, hol történik a JNI-hivatkozások allokálása és felszabadítása a kódjában, amint azt a 4. ábra mutatja.
4. ábra. Globális JNI-hivatkozások megtekintése
Az alkalmazás JNI-kódjának memóriafoglalásait csak akkor tudja megvizsgálni, ha az alkalmazást Android 8.0 vagy újabb Android 8.0-t futtató eszközre telepíti.
A JNI-vel kapcsolatos további információkért lásd: JNI tippek.
Native Memory Profiler
Az Android Studio Memory Profiler tartalmaz egy Native Memory Profiler-t az Android 10-et futtató fizikai eszközökre telepített alkalmazásokhoz; az Android 11-es eszközök támogatása jelenleg az Android Studio 4.2 előzetes kiadásában érhető el.
A Native Memory Profiler nyomon követi a natív kódban lévő objektumok allokációit/deallokációit egy adott időszak alatt, és a következő információkat adja:
- Allokációk:
malloc()
vagy anew
operátorral kiosztott objektumok száma a kiválasztott időszak alatt. - Deallokációk: A
free()
vagy adelete
operátorral a kiválasztott időszak alatt kiosztott objektumok száma. - Allokációk mérete:
- Deallokációk mérete:
- Total Count: Az Allocations oszlop értéke mínusz a Deallocations oszlop értéke.
- Maradék méret:
A felvétel elindításához kattintson a Memory Profiler ablak tetején a Natív allokációk rögzítése gombra:
Amikor készen áll a felvétel befejezésére, kattintson a Felvétel leállítása gombra.
A Natív memóriaprofilozó alapértelmezés szerint 32 bájtos mintaméretet használ: Minden alkalommal, amikor 32 bájtnyi memória kerül kiosztásra, egy pillanatfelvétel készül a memóriáról. A kisebb mintaméret gyakoribb pillanatfelvételeket eredményez, ami pontosabb adatokat szolgáltat a memóriahasználatról. A nagyobb mintaméret kevésbé pontos adatokat eredményez, de kevesebb erőforrást fogyaszt a rendszeren és javítja a teljesítményt a rögzítés során.
A Native Memory Profiler mintaméretének megváltoztatásához:
- Válassza a Futtatás > Konfigurációk szerkesztése lehetőséget.
- Válassza ki az alkalmazásmodulját a bal oldali ablakban.
- Kattintson a Profiling fülre, és adja meg a minta méretét aNative memory sampling interval (bytes) feliratú mezőben.
- Készítse el és futtassa újra az alkalmazást.
Capture a heap dump
A heap dump megmutatja, hogy az alkalmazásban mely objektumok használják a memóriát a heap dump rögzítésének időpontjában. Különösen egy hosszabb felhasználói munkamenet után a heap dump segíthet a memóriaszivárgások azonosításában, mivel megmutatja a még mindig a memóriában lévő objektumokat, amelyeknek már nem kellene ott lenniük.
A heap dump rögzítése után a következőket tekintheti meg:
- Milyen típusú objektumokat osztott ki az alkalmazás, és mindegyikből mennyit.
- Mennyi memóriát használnak az egyes objektumok.
- Hol tartják a hivatkozásokat az egyes objektumokra a kódjában.
- A hívási verem, ahol egy objektumot kiosztottak. (A hívási verem jelenleg csak az Android 7.1 és alacsonyabb verziók esetén érhető el a heapdömpinggel, ha a heapdömpinget a kiosztások rögzítése közben rögzíti.)
A heapdömping rögzítéséhez kattintson a Memory Profiler eszköztáron a Dump Java heap gombra.A heapdömping közben a Java memória mennyisége átmenetileg megnövekedhet.Ez normális, mivel a heapdömping az alkalmazással azonos folyamatban történik, és az adatok összegyűjtéséhez némi memóriára van szükség.
A heapdömping a memóriaidővonal alatt jelenik meg, és az 5. ábrán látható módon mutatja a heapben lévő összes osztálytípust.
5. ábra. A heap dump megtekintése
Ha pontosabban meg akarja határozni a dump létrehozásának időpontját, akkor adumpHprofData()
hívásával létrehozhat egy heap dumpot az alkalmazás kódjának kritikus pontján.
Az osztályok listájában a következő információkat láthatja:
- Allokációk: A heapben lévő allokációk száma.
-
Natív méret: Az adott objektumtípus által használt natív memória teljes mennyisége (bájtban). Ez az oszlop csak az Android 7.0 és újabb verziók esetén látható.
Itt látható a Java-ban kiosztott egyes objektumok memóriája, mivel az Android natív memóriát használ egyes keretosztályokhoz, például
Bitmap
. -
Sallow Size: Az adott objektumtípus által használt Java memória teljes mennyisége (bájtban).
-
Megtartott méret: Az ezen osztály összes példánya miatt megtartott memória teljes mérete (bájtban).
Az allokált objektumok listája feletti két menü segítségével kiválaszthatja, hogy melyikheap-dumpot vizsgálja, és hogyan rendezze az adatokat.
A bal oldali menüből kiválaszthatja, hogy melyik heapet vizsgálja:
- alapértelmezett heap:
- app heap: Az elsődleges heap, amelyen az alkalmazás memóriát rendel.
- image heap: A rendszerindítási kép, amely a rendszerindításkor előretöltött osztályokat tartalmazza. Az itteni allokációk garantáltan soha nem mozognak vagy mennek el.
- zygote heap: A copy-on-write heap, ahonnan egy alkalmazásfolyamat elágazik az Android rendszerben.
A jobb oldali menüből választhatjuk ki, hogyan rendezzük az allokációkat:
- Rendezés osztályok szerint: Csoportosítja az összes allokációt az osztály neve alapján. Ez az alapértelmezett.
- Rendezés csomagok szerint: Az összes allokációt a csomag neve alapján csoportosítja.
- Arrange by callstack: Az összes allokációt a megfelelő hívási verembe csoportosítja. Ez az opció csak akkor működik, ha az allokációk rögzítése közben rögzíti a heap dumpot. Még ebben az esetben is valószínűleg vannak olyan objektumok a halomban, amelyeket a rögzítés megkezdése előtt allokáltak, így ezek az allokációk jelennek meg először,egyszerűen osztálynév szerint felsorolva.
A lista alapértelmezés szerint a Retained Size oszlop szerint van rendezve. Ha más oszlop értékei szerint szeretne rendezni, kattintson az oszlop címére.
Kattintson egy osztály nevére a jobb oldali Instance View ablak megnyitásához (lásd a 6. ábrán). Minden felsorolt példány a következőket tartalmazza:
- Mélység:
- Natív méret: A példány mérete a natív memóriában.Ez az oszlop csak az Android 7.0 és újabb verziók esetén látható.
- Shallow Size: Ennek a példánynak a mérete a Java memóriában.
- Retained Size: A memória mérete, amelyet ez a példány ural (a dominator fa szerint).
6. ábra. A heapdump rögzítéséhez szükséges időtartamot az idővonal jelzi
A heap vizsgálatához kövesse a következő lépéseket:
- Böngéssze a listát, hogy megtalálja azokat az objektumokat, amelyek szokatlanul nagy heapszámmal rendelkeznek, és amelyek esetleg kiszivárogtak. Az ismert osztályok könnyebb megtalálásához kattintson az Osztálynévoszlop fejlécére az ábécé szerinti rendezéshez. Ezután kattintson egy osztály nevére. A jobb oldalon megjelenik azInstance View ablaktábla, amely az adott osztály minden példányát megmutatja, amint az a 6. ábrán látható.
- Egy másik lehetőség az objektumok gyors megtalálása a Filter gombra kattintva, vagy a Control+F (Macen Command+F) billentyűkombinációval, és az osztály vagy csomag nevének beírásával a keresőmezőbe. Módszer neve alapján is kereshet, ha a legördülő menüből kiválasztja azArrange by callstack lehetőséget. Ha reguláris kifejezéseket szeretne használni, jelölje be a Regex melletti négyzetet. Jelölje be aMatch case melletti négyzetet, ha a keresési lekérdezés nagy- és kisbetű-érzékeny.
- Az Instance View ablaktáblában kattintson egy példányra. Alul megjelenik a Referenciatábla, amely megmutatja az adott objektum minden hivatkozását.
Vagy kattintson a példány neve melletti nyílra a példány összes mezőjének megtekintéséhez, majd kattintson egy mező nevére, hogy megtekinthesse annak összes hivatkozását. Ha egy mező példányának részleteit szeretné megtekinteni, kattintson a jobb gombbal a mezőre, és válassza a Go to Instance parancsot.
- A Referenciák lapon, ha olyan hivatkozást azonosít, amely esetleg memóriát foglal, kattintson rá a jobb gombbal, és válassza a Go to Instance parancsot. Ez kiválasztja a megfelelő példányt a halomdömpingből, és megmutatja a saját példányadatait.
A halomdömpingben keressen memóriaszivárgást, amelyet a következők bármelyike okoz:
- Hosszú életű hivatkozások a
Activity
,Context
,View
,Drawable
és más olyan objektumokra, amelyek aActivity
vagyContext
tárolóra való hivatkozást tarthatnak. - Nem statikus belső osztályok, például egy
Runnable
, amelyek tarthatnak egyActivity
példányt. - Cache-ek, amelyek a szükségesnél hosszabb ideig tartanak objektumokat.
Heap dump mentése HPROF fájlként
A heap dump rögzítése után az adatok a Memory Profilerben csak a profilozó futása alatt tekinthetők meg. A profilkészítő munkamenetből való kilépéskor a heap dump elveszik. Ha tehát el akarja menteni a későbbi megtekintéshez, exportálja a heap-dumpot egy HPROF-fájlba. Az Android Studio 3.1 és újabb verziókban az Export capture to file gomb az eszköztár bal oldalán, az idővonal alatt található; az Android Studio 3.2 és újabb verziókban a Sessions ablaktábla minden Heap Dump bejegyzésének jobb oldalán található egy Export Heap Dump gomb. A megjelenő Export Asdialogban mentse el a fájlt a .hprof
fájlnév kiterjesztéssel.
Egy másik HPROF analizátor, például aJhat használatához a HPROF fájlt Android formátumból Java SE HPROF formátumba kell konvertálnia.Ezt aandroid_sdk/platform-tools/
könyvtárban található hprof-conv
eszközzel teheti meg. Futtassa a hprof-conv
parancsot két argumentummal: az eredeti HPROF fájl és a konvertált HPROF fájl írási helye. Például:
hprof-conv heap-original.hprof heap-converted.hprof
Heap dump fájl importálása
Egy HPROF (.hprof
) fájl importálásához kattintson a Start a new profiling session gombra aSessions ablakban, válassza a Load from file lehetőséget, és válassza ki a fájlt a fájlböngészőből.
A HPROF fájlt a fájlböngészőből a szerkesztő ablakba húzva is importálhatja.
Leak detection in Memory Profiler
Heap dump elemzése során a Memory Profilerben szűrheti azokat a profiladatokat, amelyek az Android Studio szerint memóriaszivárgásra utalhatnak az alkalmazás Activity
ésFragment
példányai esetében.
A szűrő által megjelenített adattípusok a következők:
-
Activity
példányok, amelyek megsemmisültek, de még mindig hivatkoznak rájuk. -
Fragment
példányok, amelyeknek nincs érvényesFragmentManager
, de még mindig hivatkoznak rájuk.
Bizonyos helyzetekben, mint például a következőkben, a szűrő hamis pozitív eredményeket adhat:
- Egy
Fragment
létrehozásra került, de még nem használták. - Egy
Fragment
példányt gyorsítótáraznak, de nem egyFragmentTransaction
részeként.
A funkció használatához először rögzítsen egy heap dumpetvagy importáljon egy heap dump fájlt az Android Studio-ba. Az esetleg memóriát szivárogtató fragmentumok és tevékenységek megjelenítéséhez jelölje be a Memory Profiler heapdump ablaktáblájában a Activity/Fragment Leaks jelölőnégyzetet a 7. ábrán látható módon.
7. ábra. A heap dump memóriaszivárgások szűrése.
Technikák a memória profilozásához
A Memory Profiler használata közben stresszelje az alkalmazás kódját, és próbáljon meg memóriaszivárgásokat keresni. A memóriaszivárgások előidézésének egyik módja az alkalmazásodban az, hogy hagyod futni egy ideig, mielőtt megvizsgálnád a heapet. A szivárgások felszivároghatnak a kupac allokációinak tetejére. Minél kisebb azonban a szivárgás, annál tovább kell futtatnia az alkalmazást ahhoz, hogy észrevegye.
A memóriaszivárgást a következő módok valamelyikével is kiválthatja:
- A készüléket különböző aktivitási állapotokban többször elforgathatja álló helyzetből álló helyzetbe, majd vissza. Az eszköz forgatása gyakran okozhat egy alkalmazás számára egy
Activity
,Context
vagyView
objektum szivárgását, mivel a rendszer létrehozza aActivity
objektumot, és ha az alkalmazás valahol máshol tart egy hivatkozást az egyik ilyen objektumra, a rendszer nem tudja összegyűjteni azt. - Váltás az alkalmazás és egy másik alkalmazás között, miközben különböző aktivitási állapotokban van (navigáljon aHome képernyőre, majd térjen vissza az alkalmazásához).
Tipp: A fenti lépéseket a themonkeyrunner testframework használatával is elvégezheti.
Megoldás: A fenti lépéseket azonkeyrunner testframework használatával is elvégezheti.