2013-01-06 9 views
12

Ho un problema con il disegno di circa 80 indicatori su una mappa di Google. Sto usando Google Maps Android API v2.75 indicatori sulla mappa -> perdite di memoria -> OutOfMemoryException

Le icone dei marcatori sono dinamiche (cambio di orario). Dopo aver aggiunto un marker alla mappa non è possibile cambiare l'icona. Perciò devo rimuovere tutti i marcatori e aggiungere di nuovo tutti i marcatori.

mMap.clear(); 
for (int i = 0; i < teams.length(); i++) { 
    team = teams.get(i); 
    point = new LatLng(tema.getLatitude(), team.getLongitude()); 

    MarkerOptions marker = new MarkerOptions().position(point).title(name).icon(BitmapDescriptorFactory.fromResource(team.getMarkerId()))); 
     mMap.addMarker(marker); 
} 

Dopo l'esecuzione di questo codice più volte (si aggiorna una volta al minuto) ottengo un OutOfMemoryExpcetion.

Quando si utilizza l'icona di marcatori più grandi, OutOfMemoryException viene lanciato più velocemente, quindi penso che il problema di memoria sia correlato all'icona bitmap che non viene riciclata correttamente.

Ho anche capito che quando si cambia la rotazione del dispositivo da orizzontale a portait e viceversa si aumenta la memoria heap utilizzata. Dopo un GC, la memoria non viene liberata.

Qualcuno sa se sto aggiungendo i marcatori in modo errato o sto affrontando un problema nell'implementazione dell'API di mappa?


ho cercato di riprodurre l'errore con l'applicazione di esempio Google Map. In android-sdk/extras/google/google_play_services/samples/maps/src/com/example/mapdemo/MarkerDemoActivity.java è possibile trovare una demo di marker. Accelerare i test ho aumentato il numero di marker creati.

int numMarkersInRainbow = 12; 

modifica

int numMarkersInRainbow = 100; 

Ora inizia la demo App, selezionare i marcatori demo e passare la rotazione del dispositivo da verticale a orizzontale e viceversa un paio di volte.

mucchio iniziale:

Heap size Allocated Free  %Used #Objects 
11,543 BM 9,898 MB 1,645 MB 85,75% 65.982 

Heap dopo un paio di orientamento cambia:

Heap size Allocated Free  %Used #Objects 
15,652 MB 11,337 MB 4,316 MB 72,43% 76.984 

Heap dopo alcune modifiche dell'orientamento:

risultato
Heap size Allocated Free  %Used #Objects 
21,312 MB 16,411 MB 4,901 MB 77,00% 111.350 

La finale sarà un OutOfMemoryExcpetion .

Un heap dump mostra alcune possibili perdite di heap: https://www.box.com/s/rsy0k22dcp267se2g1fy

L'heap dump completo: https://www.box.com/s/6lyv2p6rlc0njqxw5zgu

Aggiornamento: sembra essere correlato a una memoria che perde problema in Mappe Android V2. Vedere https://code.google.com/p/gmaps-api-issues/issues/detail?id=4766 In base al problema, è necessario risolvere il problema ma non l'ho provato personalmente.

+0

Questo articolo ti aiuterà molto, se lo leggi e intraprendi le azioni appropriate: http://developer.android.com/training/displaying-bitmaps/index.html –

+3

Andy: Grazie per il tuo suggerimento. Non sto gestendo il caricamento della bitmap da solo. È il codice di Google Maps che sta caricando le bitmap. Fornisco solo una risorsa estraibile. Ho provato a caricare i bitmap downscaled ma ho avuto gli stessi problemi. (i miei pennarelli come 2-3kb) – userM1433372

+0

Ci sono alcuni problemi di perdita con la nuova API. Speriamo che vengano sistemati presto. – Warpzit

risposta

0

Ecco un approccio che è possibile adottare come soluzione alternativa a un possibile problema dell'API ... rilevare una rotazione del dispositivo ed eliminare l'oggetto MarketOptions impostandolo su null ... quindi ri-riempirlo con i propri marcatori.

+0

Grazie. Ho provato il tuo approccio. Sfortunatamente non risolve il problema. Annullando le Opzioni Market, i drawable non vengono rilasciati. – userM1433372

1

Sì, si sta affrontando un problema molto classico e comune che affligge un sacco di sviluppatori Android ... l'OOM minaccioso.Il problema si verifica quando non si stanno pulendo completamente i vecchi drawable all'aggiornamento o alla rotazione. Per risolvere il problema, dovresti davvero scorrere i tuoi marcatori prima di mMap.clear e impostarli su null e possibilmente richiedere (non puoi forzarlo) la garbage collection chiamando System.gc().

+1

Sfortunatamente i drawable sono creati dall'API di Maps e sono completamente nascosti quindi non posso annullarli. – userM1433372

+0

È sempre possibile mantenere un riferimento agli oggetti Marker in una variabile ArrayList e aggiungere ciascun indicatore ad esso quando inizialmente si popola la mappa e si creano i marcatori. Quindi puoi scorrere l'array e azzerare ogni Marker, come suggerito nella risposta. –

0

Ogni volta che ho problemi di perdita di memoria sulla mie applicazioni, ho passare attraverso il seguente scenario

  1. carico l'applicazione
  2. eseguire l'operazione, che è sospettato di perdite di memoria (preferibilmente più di una volta, quindi è più facili da analizzare in seguito)
  3. terminare l'applicazione (premendo indietro fino a tornare alla schermata principale)
  4. analizzare la memoria di dump

I passi che uso per la mia analisi sono

  1. Aprire Istogramma
  2. Cerca il mio nome del pacchetto
  3. Verificare se ci sono dei riferimenti che non dovrebbero essere

Se ci sono perdite e hai ripetuto più volte l'operazione che perde, vedrai più istanze di frammenti, attività, visualizzazioni, ecc. Per identificare il colpevole di perdita:

  1. tasto destro del mouse su un oggetto trapelato -> oggetti List -> con riferimento in entrata
  2. scegliere uno dei riferimenti in arrivo, fare clic destro -> Percorso al GC radici -> escludere WeakReferences
  3. Aprire i livelli di stack fino a quando non identificare un riferimento. Se l'unico percorso conduce a un Finalizzatore, hai scavato troppo in profondità. Se era inconcludente, prova un altro oggetto trapelato, ripeti i passaggi.

Spiacente, non è una scienza esatta, ma porterà a suggerimenti che ti permetteranno di identificare più facilmente il codice che perde.

Problemi correlati