16

Utilizzo di 2 attività semplici. Prima azione che contiene solo un pulsante per avviare la seconda attività che detiene la mappa:API di Google Maps Android v2 Perdita di memoria SupportMapFragment di memoria

attività principale:

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
} 

public void goToMap(View view){ //This is just the onClick method for the button 
    Intent intent=new Intent(this, BigMapTest.class); 
    startActivity(intent); 
} 

L'attività di mappa:

public class BigMapTest extends FragmentActivity { 
SupportMapFragment mapFragment; 
GoogleMap map; 

@Override 
protected void onCreate(Bundle arg0) { 
    // TODO Auto-generated method stub 
    super.onCreate(arg0); 

    setContentView(R.layout.travel_diary_big_map); 

    mapFragment=(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.big_map); 
    map=mapFragment.getMap(); 

} 

Il layout XML per l'attività mappa:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" > 

<fragment 
     android:id="@+id/big_map" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     class="com.google.android.gms.maps.SupportMapFragment" 
     /> 

Ora quando eseguo questo codice, premendo il pulsante per passare all'Attività con la mappa, e premendo indietro per arrivare alla prima attività ... quindi ripetendo il processo, posso vedere l'heap aumentare di dimensioni ogni volta, fino a quando raggiunge i suoi limiti e poi inizia a bloccare. Se si scherza un po 'di più con la mappa (ad esempio lo zoom) posso ottenere un'eccezione OOM a questo punto.

01-25 16: 10: 13.931: D/dalvikvm (21578): GC_FOR_ALLOC liberato 1898K, 7% da 45859K/49187K, pausa 204ms
01-25 16: 10: 14,671: I/dalvikvm- mucchio (21578): morsetto bersaglio GC mucchio da 52.724MB a 48.000MB
01-25 16: 10: 14,671: D/dalvikvm (21578): GC_CONCURRENT liberato 2534K, 6% da 46554K/49187K, pausa 3ms + 14ms
01-25 16: 10: 15.372: I/dalvikvm-heap (21578): Clamp di destinazione GC heap da 52.979 MB a 48.000 MB
01-25 16: 10: 15.382: D/dalvikvm (21578): GC_CONCURRENT liberato 2273K, 5% gratuito 46815K/49187K, in pausa 3ms + 15ms
01-25 16: 10: 15.622: I/dalvikvm-heap (21578): Clam p target GC heap da 52.604 MB a 48.000 MB
01-25 16: 10: 15.622: D/dalvikvm (21578): GC_FOR_ALLOC liberato 657K, 6% gratuito 46431K/49187K, sospeso 202 ms
01-25 16:10: 16.203: I/dalvikvm-heap (21578): Clamp di destinazione GC heap da 52.959 MB a 48.000 MB
01-25 16: 10: 16.203: D/dalvikvm (21578): GC_FOR_ALLOC liberato 1469K, 5% libero 46796K/49187K, in pausa 217 ms
01-25 16: 10: 16.203: I/dalvikvm-heap (21578): forzatura della raccolta di SoftReferences per l'allocazione di 278744 byte
01-25 16: 10: 16.423: I/dalvikvm-heap (21578) Clamp target GC heap da 52.952 MB a 48.000 MB
01-25 16: 10: 16.423: D/dalvikvm (21578): GC_BEFORE_OOM liberato 9K, 5% libero 46786K/49187K, sospeso 219 ms
01-25 16: 10: 16.423: E/dalvikvm-heap (21578): memoria esaurita su un'allocazione di 278744 byte.

Qualsiasi suggerimento/aiuto sarebbe apprezzato.

+0

Utilizzare MAT per determinare l'origine della perdita. – CommonsWare

+1

Usare MAT e quindi cercare l'oggetto con la dimensione più grande mantenuta (che continua a crescere ad ogni ciclo), quindi usando il percorso per le radici GC escludendo i riferimenti deboli, ho raggiunto quanto segue: class maps.by.a @ 0x414f7fa8 System Class. - Ma non so cosa fare dopo. – Nims

+1

Sembra che qualcosa stia accumulando in una Hashmap: la classe "maps.by.a", caricata da "dalvik.system.PathClassLoader @ 0x413de740", occupa 12,923,112 (57,78%) byte. La memoria viene accumulata in un'istanza di "java.util.HashMap $ HashMapEntry []" caricata da "". Parole java.util.HashMap $ HashMapEntry [] maps.by.a dalvik.system.PathClassLoader @ 0x413de740 – Nims

risposta

0

Utilizzare questo nel layout:

<LinearLayout 
     android:id="@+id/map_container2" 
     android:layout_width="match_parent" 
     android:layout_height="200dp" 
     android:layout_weight="35.22" 
     android:orientation="horizontal" > 

     <fragment 
      android:id="@+id/map1" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_weight="1" 
      class="com.google.android.gms.maps.SupportMapFragment" 
      map:cameraTargetLat="40.72" 
      map:cameraTargetLng="-74.00" 
      map:cameraZoom="8" /> 
    </LinearLayout> 

E questo codice:

onCreate{ 
    setUpMapIfNeeded(); 
} 

private void setUpMapIfNeeded() { 
     // TODO Auto-generated method stub 
     // Do a null check to confirm that we have not already instantiated the map. 
     if (mMap == null) { 
      // Try to obtain the map from the SupportMapFragment. 
      mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map1)) 
        .getMap(); 
      // Check if we were successful in obtaining the map. 
      if (mMap != null) { 
       setUpMap(); 
      } 
     } 
    } 

private void setUpMap() { 
     // TODO Auto-generated method stub 
     // Hide the zoom controls as the button panel will cover it. 
     mUiSettings = mMap.getUiSettings(); 
// Enables/disables zoom gestures (i.e., double tap, pinch & stretch). 
     mMap.getUiSettings().setZoomGesturesEnabled(false); 
// Enables/disables scroll gestures (i.e. panning the map). 
     mMap.getUiSettings().setScrollGesturesEnabled(false); 
// Enables/disables the compass (icon in the top left that indicates the orientation of the 
     // map). 
     mMap.getUiSettings().setCompassEnabled(false); 
     // Add lots of markers to the map. 
     addMarkersToMap(); 

     // Pan to see all markers in view. 
     // Cannot zoom to bounds until the map has a size. 
     final View mapView = getSupportFragmentManager().findFragmentById(R.id.map1).getView(); 
     if (mapView.getViewTreeObserver().isAlive()) { 
      mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
       @SuppressLint("NewApi") // We check which build version we are using. 
       @Override 
       public void onGlobalLayout() { 
        LatLngBounds bounds = new LatLngBounds.Builder() 
          .include(WOODS) 
          .build(); 
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 
         mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        } else { 
         mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        } 
        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); 
       } 
      }); 
     } 
    } 

private void addMarkersToMap() { 
     // TODO Auto-generated method stub 
     // Uses a colored icon. 
     mWoods = mMap.addMarker(new MarkerOptions() 
       .position(WOODS) 
       .title("Woods") 
       .snippet("R. Quatá, 1016, Vila Olimpia - (11) 3849-6868") 
       .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))); 
    } 
+0

dare il codice completo –

+0

@SinghArjun, Questo è il codice completo – Marckaraujo

+0

Ciò che è WOODS qui LatLngBounds limiti = new LatLngBounds.Builder() .include (Woods) e il nome della variabile per mUiSettings –

7

Vicino posso dire da qualche investigatore base MAT, ciò che state vedendo è una cache gestito da Maps V2 dei dati della mappa scaricati. La cache sembra essere più grande se si esegue una panoramica e si ingrandisce molto. La cache si restringe se lasci la mappa e ritorni a una nuova mappa in seguito.Non ho potuto ottenere N cache da N volte che avviava l'attività della mappa della tua app di esempio, e la dimensione della cache si attenuava e fluiva a seconda di ciò che l'utente faceva.

Ahimè, questa cache è non configurabile, per quanto ne so, in termini di quanto è grande, quando viene sgomberato, fa debordare su disco, ecc

Così, per impostazione predefinita, tutto quello che puoi fare è lascia da parte una porzione buona dello spazio su heap per giocare con Maps V2 e prendi provvedimenti per rimanere all'interno di questo sottoinsieme più piccolo di heap.

Se si voleva sperimentare, si potrebbe provare a chiamare clear() su GoogleMap, o onLowMemory() sul SupportMapFragment, per vedere se c'è ne aiutano a ridurre questo dimensione della cache.

+0

Mentre alcuni dei comportamenti osservati potrebbero essere dovuti al flusso e riflusso della cache, il frammento delle mappe sta sicuramente perdendo il contesto che lo ospita. Questo può essere facilmente verificato ruotando un'attività con una mappa alcune volte e quindi vedendo quante copie dell'attività sono ancora nell'heap. Anche l'app per la demo delle mappe funziona come descritto nella [segnalazione bug] (http://code.google.com/p/gmaps-api-issues/issues/detail?id=4766). – blahdiblah

1

Ho esattamente lo stesso problema. La memoria aumenta ogni volta che inizia l'attività che ospita la mappa V2. E non viene rilasciato anche quando l'attività finisce.

Quindi la soluzione alternativa è riutilizzare quell'attività. Rendere l'attività singleTask nel manifesto e, invece di finish(), utilizzare moveTaskToBack(true);

+0

Questa è una buona soluzione se si ha solo una mappa o pochissime mappe in uso, ma non vedo come funzionerebbe se si hanno mappe in diverse attività. – Nims

+0

no non funziona –