In questo articolo Indice dei contenuti 2 sezioni
I limiti di memoria introdotti con Android 17 cambiano parecchio le regole del gioco per chi sviluppa applicazioni, perché da adesso ogni singola app si vede assegnare un tetto di RAM calcolato sulla base della memoria fisica del dispositivo su cui gira. La novità parte dai Pixel, come spesso accade, ma è destinata ad allargarsi ad altri produttori e a coprire una gamma piuttosto ampia di configurazioni, dai telefoni con 4 GB fino a quelli che superano i 16 GB. L’idea di fondo è semplice, quasi banale nella sua logica: evitare che un processo particolarmente vorace si porti dietro tutto il sistema, rendendolo lento e poco reattivo.
Il punto interessante, però, riguarda il modo in cui questo tetto viene fatto rispettare. Superare la soglia non significa automaticamente vedersi chiudere l’app in faccia. Android può prima aumentare la pressione sulla memoria e ricorrere alla zRAM, spostando alcune pagine del processo in uno spazio compresso. Una soluzione elegante sulla carta, meno indolore nella pratica, dato che comprimere e poi decomprimere costa cicli di CPU. Il risultato sono scatti, rallentamenti, un’interfaccia che perde quella fluidità che l’utente percepisce subito anche senza saper spiegare perché.
Non basta più inseguire gli errori OOM
Qui sta il cambio di prospettiva più concreto per chi lavora sul codice. Cercare soltanto le classiche eccezioni di esaurimento dell’heap Java non serve più a granché, visto che un’app può iniziare a comportarsi male molto prima di generare un errore OOM vero e proprio. La distinzione conta parecchio in fase di diagnosi, perché un processo può essere terminato per aver sforato il limite imposto dal sistema oppure per un’autentica condizione di memoria esaurita, e le due cose richiedono interventi diversi.
Per aiutare a capirci qualcosa, Android 17 registra informazioni specifiche tramite ApplicationExitInfo. Il metodo getDescription() può restituire la descrizione MemoryLimiter:AnonSwap, mentre l’exit reason associato risulta REASONOTHER. Un dettaglio tecnico, certo, ma è il tipo di indizio che fa la differenza quando si cerca di capire perché un’app si chiude sui dispositivi degli utenti e non sul banco di prova. C’è poi un altro aspetto spesso sottovalutato. La memoria da tenere d’occhio non è solo quella Java. L’invito è a guardare soprattutto l’Anonymous RSS, insieme alla memoria finita in swap, perché questa metrica include componenti che tendono a passare inosservati: buffer nativi, librerie C e C++, WebView, dati gestiti tramite JNI, motori grafici, risorse multimediali. Bitmap ad alta risoluzione, cache che crescono senza controllo, texture, framebuffer e buffer temporanei possono far salire il consumo in fretta. Un heap Java che sembra tranquillo, insomma, non garantisce affatto che l’intero processo resti sotto la soglia.
Gli strumenti per misurare e simulare
Sul fronte degli strumenti, Android Vitals permette di osservare il comportamento reale dell’applicazione attraverso metriche come Memory Usage e Bitmap Memory Usage, con la possibilità di filtrare i dati in base alla quantità di RAM del dispositivo e allo stato del processo, distinguendo tra attività in primo piano, servizi, processi in background e componenti cached. Anche Crashlytics 20.1.0 dà una mano nel raccogliere informazioni sugli OOM e sulle terminazioni provocate dal memory limiter. Il valore di questi dati cresce quando gli eventi vengono collegati alla versione dell’app, al modello del dispositivo, alla RAM disponibile e alle operazioni eseguite poco prima della chiusura. ProfilingManager, disponibile già da Android 15, consente invece di raccogliere heap dump e heap profile direttamente su dispositivi reali, con i trigger TRIGGERTYPEOOM e TRIGGERTYPE_ANOMALY che aiutano a legare la profilazione a condizioni precise senza raccogliere dati alla cieca.
Prima di pubblicare, i comandi adb della shell am permettono di verificare lo stato del limite e di simulare soglie manuali. Stringere artificialmente i vincoli è un buon modo per far venire a galla cache prive di meccanismi di espulsione, riferimenti tenuti in vita per sbaglio, allocazioni native e problemi che emergono durante le rotazioni dello schermo o nei passaggi tra primo piano e background. Una baseline dei consumi, test su più classi di RAM e il monitoraggio costante di RSS, swap, bitmap e picchi di allocazione servono a prevenire non soltanto i crash, ma anche quei rallentamenti generati dalla compressione della memoria.










