Errore di Memoria di android a causa di Heap di Dimensione Crescente

Io sono sempre errore di Memoria insufficiente. Sto lavorando sulla chat live di applicazione. Si sta lavorando bene, ma quando sono in esecuzione l’applicazione da 1 a 2 ore sul dispositivo di dimensioni heap è in aumento e, quando ha raggiunto a 16 MB di avvio dell’applicazione a stelo e di essere caduto dopo un po di tempo e mostrando out of memory due to heap size perché la risultante di heap di dimensione è maggiore di quanto allocato.

Sto testando la mia applicazione su HTC Explorer. Nella mia applicazione la maggior parte delle attività sono utilizzando thread in background e che sto usando Asnyc Attività.

Io sono sempre errore come il seguente.

04-30 16:53:14.658: E/AndroidRuntime(5707): FATAL EXCEPTION: MagentoBackground
04-30 16:53:14.658: E/AndroidRuntime(5707): java.lang.OutOfMemoryError: (Heap Size=20167KB, Allocated=16063KB, Bitmap Size=355KB)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.util.ByteArrayBuffer.<init>(ByteArrayBuffer.java:53)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.io.AbstractSessionInputBuffer.init(AbstractSessionInputBuffer.java:82)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.io.SocketInputBuffer.<init>(SocketInputBuffer.java:98)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.SocketHttpClientConnection.createSessionInputBuffer(SocketHttpClientConnection.java:83)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.conn.DefaultClientConnection.createSessionInputBuffer(DefaultClientConnection.java:170)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.SocketHttpClientConnection.bind(SocketHttpClientConnection.java:106)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.conn.DefaultClientConnection.openCompleted(DefaultClientConnection.java:129)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:173)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:359)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
04-30 16:53:14.658: E/AndroidRuntime(5707):     at com.live2support.CustomHttpClient.executeHttpPost1(CustomHttpClient.java:163)

C’è limite di dimensione heap? come posso risolvere il mio problema?

  • Post un po ‘ di codice. La mia ipotesi è che si utilizza Bitmap di grandi dimensioni all’interno di un Elenco Personalizzato.
  • …o di serie ?
  • io non sto usando bitmap nella mia applicazione.ho alcune immagini nella cartella drawable e sto usando solo che non sono molto da 15 a 20 immagini che ho.
  • non si ha realmente bisogno di tutti e la storia della chat in fase di runtime, o il mantenimento di questi cronologia chat in un array o in oggetto da collezione o il tuo elenco è troppo grande. È possibile utilizzare una crescita dinamica visualizzazione elenco .
  • al com.live2support.CustomHttpClient.executeHttpPost1(CustomHttpClient.java:163) — si sta facendo qualcosa che occupano buona quantità di memoria ogni volta..cerca di liberare la memoria come presto si utilizza questo..anche ovunque gli oggetti,arraylist,bitmap cancellare dalla memoria, come presto si usa..una volta utilizzare assegnare null e Sistema di chiamata.gc(); per indicare una bandiera al garbage collector.
  • sì, io sono il Sistema di chiamata.gc(); ovunque.
  • Anieeh non ho bisogno di storia della chat di tutti i tempi, ma somecase ho bisogno di visualizzare lo storico delle chat.
  • Il Sistema Di Chiamata.(gc) è nella maggior parte dei casi non è una soluzione. Leggere stackoverflow.com/questions/2414105/…

InformationsquelleAutor nikki | 2012-03-22



5 Replies
  1. 12

    La tua domanda ha due parti:

    1) Come è possibile determinare la dimensione dell’heap sul mio dispositivo di prova?

    2) Perché è la mia app che superano la dimensione del mio heap?

    Per quanto riguarda la domanda 1, è possibile determinare la dimensione dell’heap nel dispositivo di prova direttamente nel codice chiamando:

    Runtime.getRuntime().maxMemory();

    Vedere questo post per ulteriori informazioni su questo metodo, così come alcuni esempio di heap dimensioni sono disponibili su vari dispositivi.

    Inoltre, se si utilizza un dispositivo radicata, ci può essere un modo per impostare direttamente (e controllare) la dimensione dell’heap tramite l’interfaccia. Per esempio, in CyanogenMod varie versioni di Android, dal menu Impostazioni, è possibile selezionare “impostazioni CyanogenMod,” e poi su “Prestazioni” e quindi “VM heap size”, e di vedere (e modificare) la dimensione dell’heap per il tuo dispositivo. Fare attenzione, in quanto l’impostazione della dimensione dell’heap troppo piccolo può rendere il vostro dispositivo si comportano male o peggio.

    Per quanto riguarda la domanda 2: non hanno fornito informazioni sufficienti per diagnosticare il tuo problema specifico, e, in ogni caso, per fare una diagnosi di seconda mano è difficile al meglio. La vostra scommessa migliore per risolvere questo problema (e per imparare qualcosa di durevole di valore nel processo) sarebbe quello di acquisire familiarità con alcuni dei molto potente memoria di strumenti di analisi disponibili in Android (alcuni dei quali sono anche integrato in Eclipse IDE). Io uso questi strumenti Eclipse, in modo che è quello che descriverò di seguito.

    Prima di tutto, assicuratevi che il vostro Eclipse versione è aggiornato installando l’ultima versione di Eclipse (ad esempio, Indigo).

    Prossimo, in Eclipse, scegliere Guida/Installare Nuovo Software, quindi fare clic sulla freccia in alto e selezionare

    "Indigo - http://download.eclipse.org/releases/indigo"

    Quindi, aprire la Finalità Generale la categoria di Strumenti facendo clic sul segno più accanto a esso, e selezionare Memory Analyzer e anche la Memoria Analyzer (Grafici) [facoltativo]. Installazione di questi strumenti.

    Avanti, selezionare la Finestra delle Preferenze, e poi Android/DDMS, e selezionare il HPROF azione “Apri in Eclipse.” Questo farà sì che ogni HPROF heap dump file che si genera da DDMS essere di formato appropriato per Eclipse, e anche causare di essere aperto automaticamente in Eclipse Memory Analyzer (che è stato appena installato sopra).

    Ora, apri il DDMS selezionando Finestra/Open Perspective/Altri/DDMS. Selezionare l’icona Periferiche (sembra un telefono) sulla sinistra e trascinare la finestra risultante, in modo che è ancorata da qualche parte si può vedere facilmente.

    Assicurarsi che il dispositivo è collegato al PC via USB, e che l’applicazione è in esecuzione.

    Nella scheda Dispositivi che avete appena creato, selezionare la app in esecuzione del processo. Eseguire l’applicazione e il punto dove si è occupato di memoria sufficiente che sai che è trapelato, ma non così tanto che si blocca. Ora, fare clic su Dump HPROF icona del File nella scheda dispositivi. Dopo un breve ritardo, ti verrà offerta una scelta di relazioni sullo heap. Tenta la fuga i Sospetti di Report per iniziare. Questo report verrà aperto nella finestra Strumento di Analisi della Memoria. Ti dice dove sta usando la tua app di memoria. Controllare i vari tipi di oggetti e vedere se hanno un aspetto gonfio rispetto alla quantità di dati che ci si aspetta loro di bisogno; se è così, che potrebbe indicare una perdita.

    Qui è un bel tutorial che descrive in dettaglio come generare ed esplorare il vostro heap utilizzando DDMS e la Memory Analyzer Tool.

    Indietro nel DDMS (o il DDMS prospettiva in Eclipse), è possibile selezionare l’Assegnazione scheda Tracker mentre il dispositivo è collegato, e quindi il dispositivo dalla scheda dispositivi, quindi selezionare l’applicazione del processo dalla lista per il dispositivo. Quindi, nell’Assegnazione Tracker scheda, fare clic su Start pulsante di Rilevamento, e quindi eseguire l’applicazione di operazioni di maggiore rilevanza (quelli che si sospetta siano perdite), e quindi fare clic su Get Allocazioni pulsante e quindi selezionare la Sosta pulsante di Rilevamento.

    Visualizza tutte le allocazioni che si sono verificati, mentre sono stati tracking (non ci sono limiti per l’importo verrà store). Cliccando su uno qualsiasi di questi vi porterà a stack al momento dell’assegnazione, e cliccando su una qualsiasi parte del dump dello stack di prendere il codice sorgente che è stato coinvolto nell’assegnazione.

    Questi strumenti dovrebbe darti un’idea di cosa potrebbe essere la causa della tua app per la perdita di memoria.

    • grazie curl…………………
  2. 7

    Sembra la classica perdita di memoria. Si dice, che si utilizza AsyncTask per la connessione. E ‘ molto facile per la perdita di un contesto con un AsyncTask su modifiche di configurazione (ad esempio, la rotazione del dispositivo) quando non sai come usarlo correttamente.

    Prima cosa vi consigliamo caldamente la visione di questo: http://www.youtube.com/watch?v=_CruQY55HOk

    Per verificare se si dispone di una perdita di memoria, ruotare il dispositivo e verificare come il Garbage Collector si comporta. Si dovrebbe avere qualcosa di simile GC_... freed 211K, 71% free 300K/1024K, external 0K/0K, paused 1ms+1ms nel LogCat quasi ogni volta che si ruota. Guarda per cambiamenti in questa parte: 300K/1024K. Se non hai perdite di memoria, la prima parte deve crescere e quindi ottenere più piccoli dopo un paio di Cv. Se si dispone di una perdita di memoria, crescere e crescere, al punto di OOM errore.

    Se si assicurarsi di avere una perdita di memoria in questo modo, che cosa si dovrebbe fare è quello di installare il TAPPETO per Eclipse, imparare ad usarlo (con il suddetto film) e scoprire che cosa provoca.

    La mia personale scommessa sarebbe una cattiva attuazione della AsyncTask – non si staccano dalla distrutta Attività e collegarlo al nuovo? Se non, iniziare a farlo (c’è un ottimo esempio da CommonsWare) o passare a AsyncTaskLoader che fa per te, ed è generalmente un ottimo sostituto per il AsyncTask (non solo per il carico di roba).

    • Anche io ho avuto un problema strano con OOM di errore che appariva solo quando ho iniziato la mia app dal debugger. Quando viene avviato normalmente con icona di avvio la perdita di memoria non si verifica: stackoverflow.com/questions/10305037/…
  3. 4

    Basta aggiungere android:largeHeap="true" nell’applicazione di tag all’interno del vostro manifesta.

    • Mentre questo codice può rispondere alla domanda, fornendo informazioni aggiuntive in merito a come e/o perché non risolve il problema sarebbe di migliorare la risposta a lungo termine di valore.
  4. 1

    Il vostro heap limite di dimensione varia in base al dispositivo. 2.x dispositivo, mi aspetto circa 20 o 32 MB è il tuo limite. Vedere Android dimensione heap su diversi telefoni/dispositivi e le versioni di OS per ulteriori informazioni su dimensioni di heap.

    Dal tuo stack trace, sembra com.live2support.CustomHttpClient.executeHttpPost1() è al centro del problema.

    • allora cosa posso fare?
    • Solita roba. Mi piacerebbe provare le cose in questo ordine: 1. ispezione visiva del codice. Forse anche aggiungere una funzione a questa domanda in MODO così gli altri possono controllare. 2. il passaggio attraverso il codice utilizzo di un debugger a livello sorgente. 3. Utilizzare DDMS se 2 non fare il trucco. developer.android.com/guide/developing/debugging/ddms.html
  5. 0

    Questo può essere fatto in due modi, a seconda del sistema operativo Android.

    1. È possibile utilizzare android:largeHeap="true" applicazione di tag di Android manifesto per la richiesta di una maggiore dimensione heap, ma questo non funzionerà su qualsiasi pre dispositivi a nido d’ape.
    2. Pre 2.3 dispositivi, è possibile utilizzare il VMRuntime classe, ma questo non funziona su Gingerbread e soprattutto Vedere di seguito come fare.
    VMRuntime.getRuntime().setMinimumHeapSize(BIGGER_SIZE);

    Prima Impostazione HeapSize assicurarsi di aver inserito le dimensioni appropriate che non alterino altra applicazione o funzionalità del sistema operativo. Prima le impostazioni di verificare quanto sia la dimensione del vostro app si & quindi impostare la dimensione solo per soddisfare il tuo lavoro. Non lo uso tanto di memoria, altrimenti altre applicazioni potrebbero interessare.

    Di riferimento: http://dwij.co.in/increase-heap-size-of-android-application

Lascia un commento