Profilerul de memorie este o componentă dinAndroid Profiler care vă ajută să identificați scurgerile de memorie și aglomerările de memorie care pot duce la bâlbâieli, înghețări și chiar la blocarea aplicației. Acesta afișează un grafic în timp real al utilizării memoriei aplicației dvs. și vă permite să capturați un heap dump, să forțați garbage collections și să urmăriți alocările de memorie.
Pentru a deschide Memory Profiler, urmați acești pași:
- Click View > Tool Windows > Profiler (puteți, de asemenea, să faceți clic pe Profile în bara de instrumente).
- Selectați dispozitivul și procesul aplicației pe care doriți să le profilați din bara de instrumente AndroidProfiler. Dacă ați conectat un dispozitiv prin USB, dar nu îl vedeți listat, asigurați-vă că ați activat depanarea USB.
- Click oriunde în linia de timp MEMORY pentru a deschide Memory Profiler.
Alternativ, puteți inspecta memoria aplicației din linia de comandă cudumpsys și, de asemenea, să vedeți evenimentele GC în logcat.
De ce ar trebui să vă faceți profilul memoriei aplicației
Android oferă un mediu de memorie administrată – atunci când stabilește că aplicația dvs. nu mai folosește anumite obiecte, colectorul de gunoi eliberează memoria neutilizată înapoi în heap. Modul în care Android se ocupă de găsirea memoriei nefolosite este în mod constant îmbunătățit, dar la un moment dat, pe toate versiunile Android, sistemul trebuie să întrerupă pentru scurt timp codul dumneavoastră. De cele mai multe ori, pauzele sunt imperceptibile. Cu toate acestea, dacă aplicația dvs. alocă memorie mai repede decât o poate colecta sistemul, aplicația dvs. ar putea fi întârziată în timp ce colectorul eliberează suficientă memorie pentru a satisface alocările dvs. Întârzierea ar putea face ca aplicația dvs. să sară cadre și să provoace o încetinire vizibilă.
Inclusiv dacă aplicația dvs. nu prezintă încetinire, dacă pierde memorie, aceasta poate reține acea memorie chiar și în timp ce se află în fundal. Acest comportament poate încetini restul performanțelor de memorie ale sistemului prin forțarea evenimentelor inutile de colectare a gunoiului. În cele din urmă, sistemul este forțat să omoare procesul aplicației dvs. pentru a recupera memoria. Apoi, atunci când utilizatorul revine la aplicația dumneavoastră, aceasta trebuie să repornească complet.
Pentru a ajuta la prevenirea acestor probleme, ar trebui să folosiți Memory Profiler pentru a face următoarele:
- Căutați modele de alocare a memoriei nedorite în linia de timp care ar putea cauza probleme de performanță.
- Dump the Java heap pentru a vedea ce obiecte folosesc memoria în orice moment dat. Mai multe descărcări de heap pe o perioadă extinsă de timp pot ajuta la identificarea scurgerilor de memorie.
- Înregistrați alocările de memorie în timpul unei interacțiuni normale și extreme cu utilizatorul pentru a identifica exact unde codul dvs. fie alocă prea multe obiecte într-un timp scurt, fie alocă obiecte care devin scurgeri de memorie.
Pentru informații despre practicile de programare care pot reduce utilizarea memoriei aplicației dumneavoastră, citiți Gestionați memoria aplicației dumneavoastră.
Prezentare generală a Profilerului de memorie
Când deschideți pentru prima dată Profilerul de memorie, veți vedea o cronologie detaliată a utilizării memoriei aplicației dumneavoastră și veți avea acces la instrumente pentru a forța colectarea gunoiului, pentru a captura un heapdump și pentru a înregistra alocările de memorie.
Figura 1. Profilatorul de memorie
Așa cum este indicat în figura 1, vizualizarea implicită pentru profilatorul de memorie include următoarele:
- Un buton pentru a forța un eveniment de colectare a gunoiului.
-
Un buton pentru a captura un heap dump.
Nota: Un buton pentru a înregistra alocările de memorie apare în dreapta butonului heap dump numai atunci când este conectat la un dispozitiv care rulează Android 7.1 (nivel API 25) sau inferior.
- Un meniu derulant pentru a specifica frecvența cu care profilerul captează alocările de memorie. Selectarea opțiunii adecvate vă poate ajuta să îmbunătățiți performanța aplicației în timpul profilării.
- Butoane pentru a mări sau micșora linia de timp.
- Un buton pentru a trece înainte la datele de memorie live.
- Linia de timp a evenimentelor, care arată stările de activitate, evenimentele de introducere a datelor de către utilizator și evenimentele de rotație a ecranului.
- Linia de timp a utilizării memoriei, care include următoarele:
- Un grafic stivuit al cantității de memorie utilizată de fiecare categorie de memorie, așa cum este indicat de axa y din stânga și de cheia de culoare din partea de sus.
- O linie punctată indică numărul de obiecte alocate, așa cum este indicat de axa y din dreapta.
- O pictogramă pentru fiecare eveniment de colectare a gunoiului.
Cu toate acestea, dacă utilizați un dispozitiv care rulează Android 7.1 sau o versiune inferioară, nu toate datele de profilare sunt vizibile în mod implicit. Dacă vedeți un mesaj care spune: „Advancedprofiling is unavailable for the selected process” (Profilarea avansată nu este disponibilă pentru procesul selectat), trebuie să activați profilarea avansată pentru a vedea următoarele:
- Event timeline
- Numărul de obiecte alocate
- Evenimente de colectare a gunoiului
Pe Android 8.0 și versiunile ulterioare, profilarea avansată este întotdeauna activată pentru aplicațiile care pot fi depanate.
Cum se numără memoria
Numerele pe care le vedeți în partea de sus a profilatorului de memorie (figura 2) se bazează petoate paginile de memorie privată pe care aplicația dvs. le-a angajat, conform sistemului Android. Această numărătoare nu include paginile partajate cu sistemul sau cu alte aplicații.
Figura 2. Legenda de numărare a memoriei din partea de sus a Memory Profiler
Categoriile din numărarea memoriei sunt următoarele:
- Java: Memorie de la obiectele alocate din codul Java sau Kotlin.
-
Nativ: Memorie de la obiecte alocate din cod C sau C++.
Chiar dacă nu folosiți C++ în aplicația dumneavoastră, s-ar putea să vedeți o parte din memoria nativă utilizată aici, deoarece cadrul Android utilizează memoria nativă pentru a gestiona diverse sarcini în numele dumneavoastră, cum ar fi atunci când gestionați active de imagine și alte elemente grafice – chiar dacă codul pe care l-ați scris este în Java sau Kotlin.
-
Grafică: Memorie utilizată pentru cozile de buffer grafic pentru afișarea pixelilor pe ecran, inclusiv suprafețe GL, texturi GL și așa mai departe. (Rețineți că aceasta este memorie partajată cu CPU, nu memorie dedicată GPU.)
-
Stack: Memorie utilizată atât de stivele native, cât și de cele Java din aplicația dumneavoastră. Aceasta se referă de obicei la câte fire de execuție rulează aplicația dumneavoastră.
-
Cod: Memorie pe care aplicația dvs. o utilizează pentru cod și resurse, cum ar fi bytecode dex, cod dex optimizat sau compilat, biblioteci .so și fonturi.
-
Alții: Memorie utilizată de aplicația dvs. pe care sistemul nu este sigur cum să o clasifice.
-
Alocată: Numărul de obiecte Java/Kotlin alocate de aplicația dumneavoastră. Acest lucru nu ia în calcul obiectele alocate în C sau C++.
Când sunteți conectat la un dispozitiv care rulează Android 7.1 și versiuni mai mici, această numărătoare a alocărilor începe numai în momentul în care Memory Profiler s-a conectat la aplicația dvs. în curs de execuție. Astfel, orice obiecte alocate înainte de a începe profilarea nu sunt luate în calcul. Cu toate acestea, Android 8.0 și versiunile ulterioare include un instrument de profilare pe dispozitiv care ține evidența tuturor alocărilor, astfel încât acest număr reprezintă întotdeauna numărul total de obiecte Java restante în aplicația dvs. pe Android 8.0 și versiunile ulterioare.
În comparație cu numărătoarea memoriei din instrumentul Android Monitor anterior, noulMemory Profiler înregistrează memoria în mod diferit, astfel încât s-ar putea părea că utilizarea memoriei dvs. este acum mai mare. Memory Profiler monitorizează câteva categorii suplimentarecare măresc totalul, dar dacă vă interesează doar memoria Java heap, atuncinumărul „Java” ar trebui să fie similar cu valoarea din instrumentul anterior.Deși numărul Java probabil că nu se potrivește exact cu ceea ce ați văzut în AndroidMonitor, noul număr ține cont de toate paginile de memorie fizică care au fostalocate în Java heap al aplicației dvs. de când aceasta a fost bifurcată din Zygote. Așadar, acest lucruoferă o reprezentare exactă a cantității de memorie fizică pe care aplicația dvs. o utilizează în mod real.
Vezi alocările de memorie
Alocațiile de memorie vă arată cum a fost alocat fiecare obiect Java și referință JNI din memoria dvs. În mod specific, Memory Profiler vă poate arăta următoarele despre alocările de obiecte:
- Ce tipuri de obiecte au fost alocate și cât de mult spațiu folosesc.
- Traseul de stivă al fiecărei alocări, inclusiv în ce fir de execuție.
- Când au fost dezalocate obiectele (numai atunci când se utilizează un dispozitiv cu Android 8.0 sau o versiune mai recentă).
Dacă dispozitivul dvs. rulează Android 8.0 sau o versiune mai recentă, puteți vizualiza alocările de obiecte în orice moment, după cum urmează: Trageți în linia de timp pentru a selecta regiunea pentru care doriți să vizualizați alocările (așa cum se arată în videoclipul 1). Nu este nevoie să începeți o sesiune de înregistrare, deoarece Android 8.0 și versiunile ulterioare includ un instrument de profilare fără dispozitiv care urmărește în mod constant alocările aplicației dumneavoastră.
Video 1. Cu Android 8.0 și versiunile ulterioare, selectați o zonă de cronologie existentă pentru a vizualiza alocările de obiecte
Dacă dispozitivul dvs. rulează Android 7.1 sau o versiune inferioară, faceți clic pe Înregistrarea alocărilor de memorie în bara de instrumente Memory Profiler. În timpul înregistrării, profilatorul de memorieMemory Profiler urmărește toate alocările care au loc în aplicația dumneavoastră. Când ați terminat,faceți clic pe Stop recording (același buton; vezi video 2) pentru a vizualiza alocările.
Video 2. Cu Android 7.1 și versiunile inferioare, trebuie să înregistrațitexplicit alocările de memorie
După ce selectați o regiune din linia de timp (sau când terminați o sesiune de înregistrare cu un dispozitiv care rulează Android 7.1 sau inferior), lista obiectelor alocate apare sub linia de timp, grupate după numele clasei și ordonate în funcție de numărul lor de heap.
Pentru a inspecta înregistrarea alocării, urmați acești pași:
- Căutați în listă pentru a găsi obiecte care au un număr neobișnuit de mare de heap și care ar putea fi pierdute. Pentru a vă ajuta să găsiți clasele cunoscute, faceți clic pe antetul coloanei Class Namecolumn pentru a le sorta în ordine alfabetică. Apoi faceți clic pe un nume de clasă. În dreapta apare panoulInstance View, care arată fiecare instanță a acelei clase, așa cum se arată în figura 3.
- Alternativ, puteți localiza rapid obiectele făcând clic pe Filter,sau apăsând Control+F (Command+F pe Mac) și introducând un nume de clasă sau de pachet în câmpul de căutare. De asemenea, puteți căuta după numele metodei dacă selectațiArrange by callstack din meniul derulant. Dacă doriți să folosiți expresii regulare, bifați caseta de lângă Regex. Bifați caseta de lângăMatch case dacă interogarea dvs. de căutare este sensibilă la majuscule și minuscule.
- În panoul Instance View, faceți clic pe o instanță. Tabul Call Stackapare mai jos, arătând unde a fost alocată acea instanță și în ce fir de execuție.
- În tabul Call Stack, faceți clic dreapta pe orice linie și alegețiJump to Source pentru a deschide codul respectiv în editor.
Figura 3. Detalii despre fiecare obiect alocatapare în vizualizarea instanței din dreapta
Puteți folosi cele două meniuri de deasupra listei de obiecte alocate pentru a alege ce heap să inspectați și cum să organizați datele.
Din meniul din stânga, alegeți ce heap să inspectați:
- heap implicit: Atunci când sistemul nu specifică niciun heap.
- image heap: Imaginea de pornire a sistemului, care conține clasele care sunt preîncărcate în timpul pornirii. Alocațiile de aici sunt garantate să nu se mute niciodată sau să dispară.
- zygote heap: Heap-ul de copiere la scriere din care un proces de aplicație este bifurcat în sistemul Android.
- app heap: Heap-ul principal pe care aplicația dumneavoastră alocă memorie.
- JNI heap: Heap-ul care arată unde sunt alocate și eliberate referințele Java Native Interface (JNI).
Din meniul din dreapta, alegeți cum să aranjați alocările:
- Aranjați după clasă: Grupează toate alocările în funcție de numele clasei. Aceasta este valoarea implicită.
- Arrange by package: Grupează toate alocările pe baza numelui pachetului.
- Arrange by callstack: Grupează toate alocările în stiva de apeluri corespunzătoare.
Îmbunătățirea performanței aplicației în timpul profilării
Pentru a îmbunătăți performanța aplicației în timpul profilării, profilatorul de memorie eșantionează periodic alocările de memorie în mod implicit. Atunci când testați pe dispozitive care rulează APIlevel 26 sau mai mare, puteți schimba acest comportament utilizând meniul derulant Allocation Tracking. Opțiunile disponibile sunt următoarele:
- Full: Captează toate alocările de obiecte în memorie. Acesta este comportamentul implicit în Android Studio 3.2 și versiunile anterioare. Dacă aveți o aplicație carealocă foarte multe obiecte, este posibil să observați încetiniri vizibile cu aplicația dvs. în timpul profilării.
- Sampled: Eșantionează alocările de obiecte în memorie la intervale regulate. Aceasta este opțiunea implicită și are un impact mai mic asupra performanței aplicației în timpulprofilării. Aplicațiile care alocă o mulțime de obiecte într-un interval scurt de timp pot prezenta totuși încetiniri vizibile.
- Off: Oprește urmărirea alocării de memorie a aplicației dumneavoastră.
Vezi referințele JNI globale
Java Native Interface (JNI) este un cadru care permite codului Java și codului nativ să se apeleze reciproc.
Referințele JNI sunt gestionate manual de codul nativ, astfel încât este posibil ca obiectele Java utilizate de codul nativ să fie menținute în viață prea mult timp. Unele obiecte de pe heap-ul Java pot deveni inaccesibile dacă o referință JNI este eliminată fără a fi mai întâi ștearsă în mod explicit. De asemenea, este posibil să se epuizeze limita globală a referințelor JNI.
Pentru a soluționa astfel de probleme, utilizați vizualizarea JNI heap din Memory Profiler pentru a parcurge toate referințele JNI globale și a le filtra în funcție de tipurile Java și de call stack-urile native. Cu aceste informații, puteți afla când și unde sunt create și șterse referințele JNI globale.
În timp ce aplicația dumneavoastră rulează, selectați o porțiune din cronologie pe care doriți să o inspectați și selectați JNI heap din meniul derulant de deasupra listei de clase.Apoi puteți inspecta obiectele din heap așa cum ați face-o în mod normal și puteți face dublu clic pe obiectele din fila Allocation Call Stack pentru a vedea unde sunt alocate și eliberate referințele JNI în codul dumneavoastră, așa cum se arată în figura 4.
Figura 4. Vizualizarea referințelor JNI globale
Pentru a inspecta alocările de memorie pentru codul JNI al aplicației dumneavoastră, trebuie să vă implementați aplicațiape un dispozitiv care rulează Android 8.0 sau o versiune mai recentă.
Pentru mai multe informații despre JNI, consultați Sfaturi JNI.
Profilatorul de memorie nativă
Profilatorul de memorie Android Studio include un profilator de memorie nativă pentruaplicațiile implementate pe dispozitive fizice care rulează Android 10; suportul pentru dispozitivele Android 11este disponibil în prezent în versiunea de previzualizare Android Studio 4.2.
Profilatorul de memorie nativă urmărește alocările/dezalocările obiectelor din codul nativ pentru o anumită perioadă de timp și oferă următoarele informații:
- Alocări: O numărătoare a obiectelor alocate prin
malloc()
sau prin operatorulnew
în perioada de timp selectată. - Dealocări: Un număr de obiecte dezalocate prin
free()
sau operatoruldelete
în perioada de timp selectată. - Allocări Dimensiune: Dimensiunea agregată în octeți a tuturor alocărilor în timpul perioadei de timp selectate.
- Dealocations Size: Dimensiunea agregată în octeți a întregii memorii eliberate în timpul perioadei de timp selectate.
- Total Count: Valoarea din coloana „Allocations” minus valoarea din coloana „Deallocations”.
- Dimensiunea rămasă: Valoarea din coloana Allocations Size minus valoarea din coloana Deallocations Size.
Pentru a iniția o înregistrare, faceți clic pe Record native allocations (Înregistrare alocări native) în partea de sus a ferestreiMemory Profiler:
Când sunteți gata să finalizați înregistrarea, faceți clic pe Stop recording (Oprire înregistrare).
În mod implicit, Native Memory Profiler utilizează o dimensiune a eșantionului de 32 de octeți: De fiecare dată când sunt alocați 32 de octeți de memorie, se realizează un instantaneu al memoriei. O dimensiune mai mică a eșantionului are ca rezultat instantanee mai frecvente, producând date mai precise despre utilizarea memoriei. O dimensiune mai mare a eșantionului produce date mai puțin precise, dar va consuma mai puține resurse pe sistemul dvs. și va îmbunătăți performanța în timpul înregistrării.
Pentru a schimba dimensiunea eșantionului pentru Native Memory Profiler:
- Selectați Run > Edit Configurations.
- Select your app module in the left panel.
- Click pe fila Profiling (Profilare) și introduceți dimensiunea eșantionului în câmpul intitulatInterval de eșantionare a memoriei native (octeți).
- Construiți și rulați din nou aplicația dumneavoastră.
Capturați un heap dump
Un heap dump arată ce obiecte din aplicația dumneavoastră folosesc memoria în momentul în care capturați heap dump-ul. Mai ales după o sesiune prelungită a utilizatorului, un heap dump poate ajuta la identificarea scurgerilor de memorie, arătând obiectele încă în memorie despre care credeți că nu ar mai trebui să fie acolo.
După ce ați capturat un heap dump, puteți vizualiza următoarele:
- Ce tipuri de obiecte a alocat aplicația dvs. și câte din fiecare.
- Câtă memorie folosește fiecare obiect.
- Unde sunt ținute referințele la fiecare obiect în codul dumneavoastră.
- Stiva de apeluri pentru locul unde a fost alocat un obiect. (Stivele de apeluri sunt în prezentdisponibile cu un heap dump numai cu Android 7.1 și versiunile mai mici, atunci când capturați heap dump în timp ce înregistrați alocările.)
Pentru a captura un heap dump, faceți clic pe Dump Java heap în bara de instrumente Memory Profiler.În timp ce descărcați heap, cantitatea de memorie Java ar putea crește temporar.Acest lucru este normal, deoarece vidarea heap are loc în același proces ca și aplicația dvs. și necesită o anumită cantitate de memorie pentru a colecta datele.
Vacuarea heap apare sub linia de timp a memoriei, arătând toate tipurile de clase din heap, așa cum se arată în figura 5.
Figura 5. Vizualizarea heap dump-ului
Dacă aveți nevoie să fiți mai precis cu privire la momentul creării dump-ului, puteți crea un heap dump în punctul critic din codul aplicației dvs. apelânddumpHprofData()
.
În lista de clase, puteți vedea următoarele informații:
- Allocări: Numărul de alocări în heap.
-
Native Size: Cantitatea totală de memorie nativă utilizată de acest tip de obiect (în octeți). Această coloană este vizibilă numai pentru Android 7.0 și versiunile ulterioare.
Vă veți vedea aici memoria pentru unele obiecte alocate în Java, deoarece Android utilizează memoria nativă pentru unele clase cadru, cum ar fi
Bitmap
. -
Shallow Size: Cantitatea totală de memorie Java utilizată de acest tip de obiect (în octeți).
-
Dimensiunea reținută: Dimensiunea totală a memoriei reținute din cauza tuturor instanțelor acestei clase (în octeți).
Puteți utiliza cele două meniuri de deasupra listei de obiecte alocate pentru a alege ce heap dumps să inspectați și cum să organizați datele.
Din meniul din stânga, alegeți ce heap să inspectați:
- heap implicit: Atunci când sistemul nu specifică niciun heap.
- app heap: Heap-ul principal pe care aplicația dumneavoastră alocă memorie.
- image heap: Imaginea de pornire a sistemului, care conține clasele care sunt preîncărcate în timpul pornirii. Alocațiile de aici sunt garantate să nu se mute niciodată sau să plece.
- zygote heap: The copy-on-write heap where an app process is forked fromîn sistemul Android.
Din meniul din dreapta, alegeți cum să aranjați alocările:
- Arrange by class: Grupează toate alocările în funcție de numele clasei. Aceasta este valoarea implicită.
- Arrange by package: Grupează toate alocările pe baza numelui pachetului.
- Arrange by callstack: Grupează toate alocările în stiva de apeluri corespunzătoare. Această opțiune funcționează numai dacă capturați heap dump în timpul înregistrăriialocărilor. Chiar și așa, este probabil să existe obiecte în heap care au fostalocate înainte de a începe înregistrarea, astfel încât aceste alocări apar primele,listate pur și simplu în funcție de numele clasei.
Lista este ordonată în mod implicit după coloana Retained Size. Pentru a sorta după valorile dintr-o altă coloană, dați clic pe titlul coloanei respective.
Dați clic pe numele unei clase pentru a deschide fereastra Instance View din dreapta (prezentată în figura 6). Fiecare instanță listată include următoarele:
- Depth: Cel mai scurt număr de salturi de la orice rădăcină GC până la instanța selectată.
- Native Size: Dimensiunea acestei instanțe în memoria nativă.Această coloană este vizibilă numai pentru Android 7.0 și versiunile ulterioare.
- Shallow Size: Dimensiunea acestei instanțe în memoria Java.
- Retained Size: Dimensiunea memoriei pe care această instanță o domină (conform arborelui dominator).
Figura 6. Durata necesară pentru a capta un heapdump este indicată în cronologie
Pentru a inspecta heap-ul, urmați acești pași:
- Căutați în listă pentru a găsi obiectele care au un număr neobișnuit de mare de heap și care ar putea avea scurgeri. Pentru a vă ajuta să găsiți clasele cunoscute, faceți clic pe antetul coloanei Class Namecolumn pentru a le sorta în ordine alfabetică. Apoi faceți clic pe un nume de clasă. În dreapta apare panoulInstance View, care arată fiecare instanță a acelei clase, așa cum se arată în figura 6.
- Alternativ, puteți localiza rapid obiectele făcând clic pe Filter,sau apăsând Control+F (Command+F pe Mac) și introducând un nume de clasă sau de pachet în câmpul de căutare. De asemenea, puteți căuta după numele metodei dacă selectațiArrange by callstack din meniul derulant. Dacă doriți să folosiți expresii regulare, bifați caseta de lângă Regex. Bifați caseta de lângăMatch case dacă interogarea dvs. de căutare este sensibilă la majuscule și minuscule.
- În panoul Instance View, faceți clic pe o instanță. Tabloul de referințe apare mai jos, arătând fiecare referință la acel obiect.
Sau faceți clic pe săgeata de lângă numele instanței pentru a vizualiza toate câmpurile acesteia, apoi faceți clic pe numele unui câmppentru a vizualiza toate referințele acestuia. Dacă doriți să vizualizați detaliile instanței pentru un câmp, faceți clic dreapta pe câmp și selectați Go to Instance.
- În fila References, dacă identificați o referință care ar putea pierde memorie, faceți clic dreapta pe ea și selectați Go to Instance. Acest lucru selectează instanța corespunzătoare din heap dump, arătându-vă propriile sale date de instanță.
În heap dump, căutați scurgeri de memorie cauzate de oricare dintre următoarele:
- Referințe cu durată lungă de viață la
Activity
,Context
,View
,Drawable
și alte obiecte care ar putea deține o referință la containerulActivity
sauContext
. - Classe interne nestatice, cum ar fi un
Runnable
, care pot deține o instanțăActivity
. - Cachete care păstrează obiecte mai mult timp decât este necesar.
Salvați un heap dump ca fișier HPROF
După ce ați capturat un heap dump, datele pot fi vizualizate în Memory Profiler numai în timp ce profilerul este în execuție. Când ieșiți din sesiunea de creare a profilului, pierdeți descărcareaheap dump. Prin urmare, dacă doriți să o salvați pentru a o examina mai târziu, exportați heap dump într-un fișier HPROF. În Android Studio 3.1 și versiunile inferioare, butonul Export capture to file se află în partea stângă a barei de instrumente, sub linia de timp; înAndroid Studio 3.2 și versiunile superioare, există un buton Export Heap Dump în partea dreaptă a fiecărei intrări Heap Dump din panoul Sessions. În fereastra Export Asdialog care apare, salvați fișierul cu extensia de nume de fișier .hprof
.
Pentru a utiliza un alt analizor HPROF, cum ar fijhat, trebuie să convertiți fișierul HPROF din formatul Android în formatul Java SE HPROF. puteți face acest lucru cu instrumentul hprof-conv
furnizat în directorulandroid_sdk/platform-tools/
. Rulați comanda hprof-conv
comandă cu două argumente: fișierul HPROF original și locația în care se va scrie fișierul HPROF convertit. De exemplu:
hprof-conv heap-original.hprof heap-converted.hprof
Import a heap dump file
Pentru a importa un fișier HPROF (.hprof
), faceți clic pe Start a new profiling session în panoulSessions, selectați Load from file (Încărcare din fișier) și alegeți fișierul din browserul de fișiere.
De asemenea, puteți importa un fișier HPROF trăgându-l din browserul de fișiere într-o fereastră de editare.
Detectarea scurgerilor în Memory Profiler
Când analizați un heap dump în Memory Profiler, puteți filtra datele de profilare despre care Android Studio crede că ar putea indica scurgeri de memorie pentru Activity
șiFragment
instanțe din aplicația dvs.
Tipurile de date pe care le afișează filtrul includ următoarele:
-
Activity
instanțe care au fost distruse, dar care sunt încă referite. -
Fragment
instanțe care nu au unFragmentManager
valid, dar care sunt încă referite.
În anumite situații, cum ar fi următoarele, filtrul ar putea da rezultate falspozitive:
- Un
Fragment
este creat, dar nu a fost încă utilizat. - Un
Fragment
se află în memoria cache, dar nu ca parte a unuiFragmentTransaction
.
Pentru a utiliza această caracteristică, mai întâi capturați un heap dump sau importați un fișier heap dump în Android Studio. Pentru a afișa fragmentele și activitățile care poate au scurgeri de memorie, selectați caseta de selectare Activity/Fragment Leaks (Scurgeri de activitate/fragment) în panoul heapdump al Memory Profiler (Profilatorul de memorie), după cum se arată în figura 7.
Figura 7. Filtrarea unui heap dump pentru scurgeri de memorie.
Tehnici de profilare a memoriei
În timp ce folosiți Memory Profiler, ar trebui să vă stresați codul aplicației și să încercați să căutați scurgeri de memorie. O modalitate de a provoca scurgeri de memorie în aplicația dvs. este să o lăsați să ruleze pentru o vreme înainte de a inspecta heap-ul. S-ar putea ca scurgerile să se strecoare până în partea de sus a alocărilor din heap. Cu toate acestea, cu cât scurgerea este mai mică, cu atât mai mult timp trebuie să rulați aplicația pentru a o vedea.
Puteți, de asemenea, să declanșați o scurgere de memorie într-unul din următoarele moduri:
- Rotiți dispozitivul din portret în peisaj și înapoi de mai multe ori în timp ce se află în diferite stări de activitate. Rotirea dispozitivului poate determina adesea ca o aplicație să provoace o scurgere de memorie a unui obiect
Activity
,Context
, sauView
, deoarece sistemulrecreeazăActivity
și dacă aplicația dvs. deține o referință la unul dintre aceste obiecte în altă parte, sistemul nu îl poate colecta la gunoi. - Schimbați între aplicația dvs. și o altă aplicație în timp ce vă aflați în diferite stări de activitate (navigați până la ecranulHome, apoi reveniți la aplicația dvs.).
Tip: Puteți, de asemenea, să efectuați pașii de mai sus utilizând cadrul de testare monkeyrunner.
.