Autore Topic: Out of memory troppo frequente  (Letto 625 volte)

Offline Giacomo79

  • Utente junior
  • **
  • Post: 123
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus One
  • Play Store ID:
    Big and Fish
  • Sistema operativo:
    Android 2.3
Out of memory troppo frequente
« il: 19 Novembre 2014, 21:21:23 CET »
0
Salve a tutti,
è possibile che la mia app mi vada in out of memory molto frequentemente?

Ho un activity con 2 immagini di 100kb l'una (è tanto secondo voi o sto nella norma?), e quando la lancio la prima volta non ho problemi, se dopo qualche attività (in un'altra activity) ci ritorno ottengo un out of memory. Ma l'activity non dovrebbe essere stata buttata con conseguente liberazione della memoria?

Non riesco a capire come risolvere una volta per tutte il problema dell'out of memory. Scalo già le immagini con il codice suggerito da GG.

Grazie

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Out of memory troppo frequente
« Risposta #1 il: 20 Novembre 2014, 07:42:34 CET »
0
La dimensioni in kB delle immagini conta relativamente. Molto più importante è la dimensione in pixel, perchè in memoria sono conservate decompresse.

O potresti avere un memory leakage, ma questo è visibile sono con una attenta analisi del codice.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 618
  • Respect: +136
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Out of memory troppo frequente
« Risposta #2 il: 20 Novembre 2014, 11:48:17 CET »
0
Potrebbe tornarti utile questo articolo di Romain Guy: Avoid memory leaks on Android
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline wlf

  • Utente normale
  • ***
  • Post: 335
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Out of memory troppo frequente
« Risposta #3 il: 20 Novembre 2014, 15:25:30 CET »
0
Potrebbe tornarti utile questo articolo di Romain Guy: Avoid memory leaks on Android

Innanzi tutto l'articolo è del 2008; sono ancora valide queste accortezze oppure nel frattempo le cose sono cambiate? ;)

I primi due consigli sono abbastanza chiari, non mi è chiaro invece il terzo consiglio. (Avoid non-static inner classes in an activity if you don’t control their life cycle, use a static inner class and make a weak reference to the activity inside)

Immagino che per classi interne in un activity se non si controlla il loro ciclo di vita faccia riverimento soprattutto agli asyncTask; praticamente dovremmo quindi dichiararli statici mentre il loro riferimento per chiamarli weak?


Offline LinkOut

  • Utente normale
  • ***
  • Post: 270
  • Respect: +38
    • Mostra profilo
  • Dispositivo Android:
    Xiaomi Mi5
Re:Out of memory troppo frequente
« Risposta #4 il: 20 Novembre 2014, 15:31:04 CET »
0
Questo problema l'ho riscontrato particolarmente accentuato sul Samsung S3 e sui samsung in generale.

Su che telefono lo stai provando?

Offline wlf

  • Utente normale
  • ***
  • Post: 335
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Out of memory troppo frequente
« Risposta #5 il: 20 Novembre 2014, 15:39:07 CET »
0
Questo problema l'ho riscontrato particolarmente accentuato sul Samsung S3 e sui samsung in generale.


Effettivamente anche il Note 3 di Samsung mi capita abbastanza spesso, ma è un utente che tiene aperto decine di App contemporaneamente.

Citazione
Su che telefono lo stai provando?

Il l'ho notato frequentemente sul LG G2; comunque a me è sembrato che sia legato anche alla definizione video, più alta è più spesso capita l'errore, con i video HD o qHD o minori il problema tende a sparire ...

Offline Ohmnibus

  • Utente senior
  • ****
  • Post: 618
  • Respect: +136
    • Google+
    • @ohmnibus
    • Mostra profilo
    • Lords of Knowledge GdR
  • Dispositivo Android:
    Samsung Galaxy Nexus
  • Play Store ID:
    Ohmnibus
  • Sistema operativo:
    Windows 7 x64
Re:Out of memory troppo frequente
« Risposta #6 il: 20 Novembre 2014, 17:02:08 CET »
0
Il problema delle classi interne -non statiche- è che mantengono un riferimento al loro genitore. Di conseguenza se il loro ciclo di vita non è gestito si rischia di mantenere tale riferimento, impedendone l'eliminazione tramite garbage collector.

In pratica se in un'activity ho:

Codice (Java): [Seleziona]
private class Bad {
//qualsiasi cosa
}

static Bad bad = null;

protected void onCreate(Bundle state) {
  super.onCreate(state);

  if (bad == null) {
    bad = new Bad();
  }
}

succede che quando ruoto l'applicazione l'activity viene ri-creata, ma l'istanza (statca) di "bad" porta con se il riferimento all'activity che è stata appena distrutta, impedendo di fatto al GC di eliminarla dalla memoria.

La soluzione consiste nel dichiarare Bad come classe statica:

Codice (Java): [Seleziona]
private static class Bad {
//qualsiasi cosa
}

static Bad bad = null;

protected void onCreate(Bundle state) {
  super.onCreate(state);

  if (bad == null) {
    bad = new Bad();
  }
}

in questo modo le istanze di Bad non hanno riferimenti all'istanza padre

Post unito: 20 Novembre 2014, 17:09:53 CET
La parte interessante dell'articolo è quella relativa ai drawable.

In pratica ogni volta che fai un setBackgroundDrawable (ad esempio) crei un doppio riferimento tra la View ed il Drawable che può portare facilmente a memory leak.

Il problema può essere ridotto eliminando i riferimenti tra le View ed i relativi drawable nella OnDestroy:

Codice (Java): [Seleziona]
public class MiaActivity extends Activity {

        @Override
        protected void onDestroy() {
                super.onDestroy();
               
                unbindDrawables(findViewById(android.R.id.content));
               
                System.gc();
        }
       
        private void unbindDrawables(View view) {
                if (view != null) {
                        if (view.getBackground() != null) {
                                view.getBackground().setCallback(null);
                        }
                        if (view instanceof ViewGroup && !(view instanceof AdapterView)) {
                                for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
                                        unbindDrawables(((ViewGroup) view).getChildAt(i));
                                }
                                ((ViewGroup) view).removeAllViews();
                        }
                }
        }
}
« Ultima modifica: 20 Novembre 2014, 17:09:53 CET da Ohmnibus, Reason: Merged DoublePost »
Ohmnibus
Le mie app su Play Store

È stata trovata una soluzione al tuo problema? Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato.

Offline arlabs

  • Utente normale
  • ***
  • Post: 430
  • Respect: +49
    • Mostra profilo
  • Dispositivo Android:
    GalaxyS6, Nexus5
  • Play Store ID:
    AR Labs
  • Sistema operativo:
    Windows 10
Re:Out of memory troppo frequente
« Risposta #7 il: 20 Novembre 2014, 18:11:21 CET »
0
Quello dell'unbindDrawables l'avevo fatto pure io... avevo un po' di error di out of memory e cercavo di risolverli.

Attenzione però che potenzialmente, se non stai attento, solleva altri bug. Quello che mi succedeva era che, non ricordo i dettagli, avevo delle chiamate anche dopo la onDestroy (e non erano altri thread, ma l'UIThread) dopo i quali andavo a cercare delle view che non trovavo più.

Tra l'altro, a me, gli out-of-memory non sono diminuti con questa strategia.
Alla fine me ne sono fregato... non ho visto nessuno che si lamenta sulle recensioni per i crash.

Ciao.

Post unito: 20 Novembre 2014, 18:16:35 CET
Ho controllato, ciò che mi arrivava dopo la OnDestroy erano 2 cose:

- La chiamata all'AdListener.onAdLoaded dell'Interstitial
- un Runnable che avevo lanciato con postDelay

« Ultima modifica: 20 Novembre 2014, 18:16:35 CET da arlabs, Reason: Merged DoublePost »

Offline Giacomo79

  • Utente junior
  • **
  • Post: 123
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Google Nexus One
  • Play Store ID:
    Big and Fish
  • Sistema operativo:
    Android 2.3
Re:Out of memory troppo frequente
« Risposta #8 il: 20 Novembre 2014, 18:46:38 CET »
0
L'articolo l'ho già letto, mentre il problema io ce l'ho sull'emulatore.

Comunque non ho ancora capito perchè ottengo l'errore solo la seconda volta che attivo l'activity. Le immagini non dovrebbero essere scaricate dalla memoria quando esco dall'activity?
« Ultima modifica: 20 Novembre 2014, 19:39:41 CET da Giacomo79 »