La RAM sta diventando un fattore sempre più importante per la stabilità delle applicazioni Android.
Con Android 17, Google introduce limiti di memoria per singola app calcolati in base alla memoria disponibile sul dispositivo. La misura, inizialmente destinata ai Pixel, sarà estesa progressivamente ad altri produttori e a telefoni con configurazioni comprese tra 4 GB e oltre 16 GB.
L’obiettivo è impedire che un processo troppo esigente renda meno reattivo l’intero sistema. Per gli sviluppatori, però, cambia il modo di analizzare i consumi: non basta più cercare i tradizionali errori OOM. Android può infatti intervenire prima, utilizzando zRAM per comprimere le pagine di memoria. Questa operazione riduce il rischio di una chiusura immediata, ma aumenta il carico sulla CPU e può causare rallentamenti, scatti e una risposta meno fluida dell’interfaccia.
Come funzionano i limiti di memoria
Android 17 applica soglie variabili in funzione della memoria fisica del dispositivo. Il raggiungimento del limite non comporta necessariamente la terminazione immediata dell’applicazione. Il sistema può prima aumentare la pressione sulla memoria e ricorrere alla zRAM, spostando nello spazio compresso alcune pagine del processo.
La compressione e la successiva decompressione richiedono risorse della CPU. Per questo un’app può iniziare a mostrare problemi di fluidità anche senza generare un’eccezione di esaurimento dell’heap Java. Se il consumo continua a crescere, Android può terminare il processo. Questa distinzione è importante durante la diagnosi. Un processo può essere chiuso perché ha superato il limite imposto dal sistema oppure per un’autentica condizione OOM. Android 17 registra informazioni specifiche tramite ApplicationExitInfo: getDescription() può restituire la descrizione MemoryLimiter:AnonSwap, mentre l’exit reason associato è REASON_OTHER.
La memoria da controllare non è soltanto quella Java. Google invita a osservare soprattutto l’Anonymous RSS, insieme alla memoria in swap. Questa metrica comprende anche componenti spesso trascurati, come buffer nativi, librerie C/C++, WebView, dati gestiti tramite JNI, motori grafici e risorse multimediali.
Bitmap ad alta risoluzione, cache eccessive, texture, framebuffer e buffer temporanei possono far crescere rapidamente il consumo. Di conseguenza, un heap Java apparentemente sotto controllo non garantisce che l’intero processo rispetti la soglia disponibile.
Diagnosi e ottimizzazione sul campo
Android Vitals permette di osservare il comportamento reale dell’app attraverso metriche come Memory Usage e Bitmap Memory Usage. I dati possono essere analizzati in base alla quantità di RAM del dispositivo e allo stato del processo, distinguendo attività in primo piano, servizi, processi in background e componenti cached.
Anche Crashlytics 20.1.0 può contribuire a raccogliere informazioni sugli OOM e sulle terminazioni causate dal memory limiter. Il valore aumenta quando gli eventi vengono collegati alla versione dell’app, al modello del dispositivo, alla RAM disponibile e alle operazioni eseguite prima della chiusura.
ProfilingManager, disponibile da Android 15, consente inoltre di raccogliere heap dump e heap profile su dispositivi reali. I trigger TRIGGER_TYPE_OOM e TRIGGER_TYPE_ANOMALY aiutano a collegare la profilazione a condizioni specifiche, evitando raccolte indiscriminate.
Prima della distribuzione, i comandi adb della shell am permettono di verificare lo stato del limite e di simulare soglie manuali. Imporre condizioni più restrittive può far emergere cache prive di espulsione, riferimenti mantenuti accidentalmente, allocazioni native e problemi durante rotazioni o passaggi tra foreground e background.
La gestione della memoria diventa quindi una parte ordinaria della manutenzione. Una baseline dei consumi, test su più classi di RAM e il monitoraggio di RSS, swap, bitmap e picchi di allocazione aiutano a prevenire non solo i crash, ma anche i rallentamenti causati dalla compressione della memoria.