Prostředí Android Runtime (ART) a virtuální stroj Dalvik používají ke správě paměti stránkování a mapování paměti (mmapping). To znamená, že veškerá paměť, kterou aplikace upraví – ať už alokací nových objektů nebo zásahem do mmapovaných stránek – zůstává rezidentní v paměti RAM a nelze ji stránkovat. Jediný způsob, jak uvolnit paměť aplikace, je uvolnit reference na objekty, které aplikace drží, a zpřístupnit tak paměť garbage collectoru. To platí s jednou výjimkou: všechny soubory mmapované bez úprav, například kód, lze z paměti RAM stránkovat, pokud chce systém tuto paměť použít jinde.
Tato stránka vysvětluje, jak systém Android spravuje procesy aplikací a přidělování paměti. Další informace o tom, jak efektivněji spravovat paměť v aplikaci, najdete v části Správa paměti aplikace.
Sběr odpadu
Prostředí se spravovanou pamětí, jako je virtuální stroj ART nebo Dalvik, sleduje každou alokaci paměti. Jakmile zjistí, že část paměti již není programem využívána, uvolní ji zpět na haldu, a to bez jakéhokoli zásahu programátora. Mechanismus zpětného získávání nepoužívané paměti v prostředí spravované paměti se nazývá garbage collection. Sběr odpadu má dva cíle: najít datové objekty v programu, ke kterým již v budoucnu nebude možné přistupovat, a získat zpět prostředky, které tyto objekty používají.
Paměťová halda systému Android je generační, což znamená, že se v ní sledují různé zásobníky alokací podle očekávané životnosti a velikosti alokovaného objektu. Například nedávno alokované objekty patří do generace Young. Když objekt zůstane aktivní dostatečně dlouho, může být povýšen do starší generace, po níž následuje generace trvalá.
Každá generace haldy má svůj vyhrazený horní limit množství paměti, které v ní mohou objekty zabírat. Kdykoli se generace začne plnit, systém provede akci garbage collection ve snaze uvolnit paměť. Délka trvání garbage collection závisí na tom, která generace objektů se vybírá a kolik aktivních objektů se v každé generaci nachází.
Přestože garbage collection může být poměrně rychlý, může mít vliv na výkon aplikace. Zpravidla nemůžete z kódu ovlivnit, kdy dojde k události garbage collection. Systém má běžící sadu kritérií, podle kterých určuje, kdy provést garbage collection. Když jsou kritéria splněna, systém ukončí provádění procesu a zahájí vybírání odpadu. Pokud k vybírání odpadu dojde uprostřed intenzivní smyčky zpracování, například animace nebo během přehrávání hudby, může to prodloužit dobu zpracování. Toto prodloužení může potenciálně posunout provádění kódu v aplikaci za doporučenou hranici 16 ms pro efektivní a plynulé vykreslování snímků.
Navíc může tok kódu vykonávat takové druhy práce, které nutí k častějšímu výskytu událostí garbage collection nebo způsobují, že trvají déle, než je obvyklé. Pokud například alokujete několik objektů v nejvnitřnější části smyčky for během každého snímku animace prolínání alfa, můžete znečistit hromadu paměti velkým množstvím objektů. Za těchto okolností provede garbage collector více událostí garbage collection a může snížit výkon vaší aplikace.
Další obecné informace o garbage collection najdete v části Garbage collection.
Sdílení paměti
Aby se do paměti RAM vešlo vše potřebné, snaží se systém Android sdílet stránky RAM mezi procesy. Může tak činit následujícími způsoby:
- Každý proces aplikace je rozvětven z existujícího procesu nazvaného Zygote. Proces Zygote se spouští při startu systému a načítá společný kód frameworku a zdroje (například témata aktivit). Pro spuštění nového procesu aplikace systém forkne proces Zygote a poté načte a spustí kód aplikace v novém procesu. Tento přístup umožňuje, aby většina stránek paměti RAM určených pro kód a prostředky frameworku byla sdílena všemi procesy aplikace.
- Většina statických dat je mmapována do procesu. Tato technika umožňuje sdílení dat mezi procesy a také jejich stránkování v případě potřeby. Mezi příklady statických dat patří např: Dalvik kód (umístěním do předem propojeného
.odex
souboru pro přímé mmapování), zdroje aplikace (navržením tabulky zdrojů jako struktury, kterou lze mmapovat, a zarovnáním položek zip APK) a tradiční prvky projektu, jako je nativní kód v.so
souborech. - Na mnoha místech Android sdílí stejnou dynamickou paměť RAM napříč procesy pomocí explicitně alokovaných oblastí sdílené paměti (buď pomocí ashmem, nebo gralloc). Například plochy oken používají sdílenou paměť mezi aplikací a kompozitorem obrazovky a vyrovnávací paměti kurzoru používají sdílenou paměť mezi poskytovatelem obsahu a klientem.
Vzhledem k rozsáhlému používání sdílené paměti vyžaduje určení množství paměti, které aplikace využívá, opatrnost. Techniky pro správné určení využití paměti aplikace jsou popsány v části Zkoumání využití operační paměti.
Přidělování a zpětné získávání paměti aplikace
Hromada Dalvik je omezena na jeden rozsah virtuální paměti pro každý proces aplikace. Tím je definována logická velikost haldy, která může růst podle potřeby, ale pouze do limitu, který systém definuje pro každou aplikaci.
Logická velikost haldy není totožná s velikostí fyzické paměti, kterou halda využívá. Při kontrole haldy aplikace Android vypočítá hodnotu nazvanou Proportional Set Size (PSS), která zohledňuje špinavé i čisté stránky sdílené s ostatními procesy – ale pouze v množství, které je úměrné tomu, kolik aplikací tuto paměť RAM sdílí. Tento součet (PSS) systém považuje za vaši fyzickou paměťovou stopu. Další informace o PSS najdete v příručce Zkoumání využití vaší paměti RAM.
Hromada Dalvik nekomprimuje logickou velikost haldy, což znamená, že systém Android nedefragmentuje haldu, aby uzavřel prostor. Systém Android může zmenšovat logickou velikost haldy pouze tehdy, když je na konci haldy nevyužité místo. Systém však přesto může zmenšit fyzickou paměť používanou hromadou. Po garbage collection Dalvik prochází haldu a vyhledává nepoužívané stránky, poté tyto stránky vrací jádru pomocí madvise. Párová alokace a dealokalizace velkých kusů by tedy měla vést k rekultivování veškeré (nebo téměř veškeré) použité fyzické paměti. Rekultivace paměti z malých alokací však může být mnohem méně efektivní, protože stránka použitá pro malou alokaci může být stále sdílena s něčím jiným, co ještě nebylo uvolněno.
Omezit paměť aplikací
Aby bylo zachováno funkční prostředí pro více úloh, nastavuje systém Android pevný limit velikosti haldy pro každou aplikaci. Přesný limit velikosti haldy se u jednotlivých zařízení liší podle toho, kolik paměti RAM má zařízení celkově k dispozici. Pokud vaše aplikace dosáhne kapacity haldy a pokusí se alokovat více paměti, může obdržet hlášení OutOfMemoryError
.
V některých případech se můžete chtít dotázat systému, abyste přesně zjistili, kolik místa na haldě máte v aktuálním zařízení k dispozici – například abyste určili, kolik dat je bezpečné uchovávat v mezipaměti. Na tento údaj se můžete systému zeptat voláním getMemoryClass()
. Tato metoda vrátí celé číslo udávající počet megabajtů dostupných pro haldu vaší aplikace.
Přepínání aplikací
Když uživatelé přepínají mezi aplikacemi, systém Android uchovává aplikace, které nejsou v popředí – to znamená, že je uživatel nevidí nebo na nich neběží služba v popředí, například přehrávání hudby – v mezipaměti. Například když uživatel poprvé spustí aplikaci, vytvoří se pro ni proces; když však uživatel aplikaci opustí, tento proces se neukončí. Systém tento proces uchovává v mezipaměti. Pokud se uživatel později k aplikaci vrátí, systém proces znovu použije, čímž zrychlí přepínání aplikace.
Pokud má vaše aplikace proces uložený v mezipaměti a uchovává prostředky, které aktuálně nepotřebuje, pak vaše aplikace – i když ji uživatel nepoužívá – ovlivňuje celkový výkon systému. Jakmile systém vyčerpá zdroje, například paměť, zabije procesy v mezipaměti. Systém také počítá s procesy, které zadržují nejvíce paměti, a může je ukončit, aby uvolnil paměť RAM.
Poznámka: Čím méně paměti vaše aplikace spotřebuje, když je v mezipaměti, tím větší má šanci, že nebude zabita a bude moci rychle pokračovat. V závislosti na okamžitých požadavcích systému je však možné, že procesy uložené v mezipaměti budou kdykoli ukončeny bez ohledu na využití prostředků.
Další informace o tom, jak jsou procesy ukládány do mezipaměti, když neběží v popředí, a jak systém Android rozhoduje o tom, které z nich mohou být zabity, najdete v příručce Procesy a vlákna.