16

Использование 2 простых действий. Первая активность, которая содержит только кнопку, чтобы начать 2-ую активность, которая держит карту:Google Maps Android API v2 SupportMapFragment memory leak

Основная деятельность:

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); 
} 

Карта активности:

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(); 

} 

XML-формат для отображения активности:

<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" 
     /> 

Теперь, когда я запускаю этот код, нажимая кнопку, чтобы перейти к Activity с картой, и нажимая назад, чтобы перейти к первому действию ... затем, повторив этот процесс, я вижу, что куча увеличивается каждый раз, пока он достигает своих пределов, а затем начинает зажимать. Если вы немного сокрушаетесь с картой (т. Е. Масштабирование), я могу получить исключение OOM на этом этапе.

01-25 16: 10: 13,931 D/dalvikvm (+21578): GC_FOR_ALLOC освободил 1898K, 7% бесплатно 45859K/49187K, остановился 204ms
01-25 16: 10: 14.671: Я/dalvikvm- куча (21578): Захват целевой GC-кучи от 52.724MB до 48.000MB
01-25 16: 10: 14.671: D/dalvikvm (21578): GC_CONCURRENT освобожден 2534K, 6% бесплатно 46554K/49187K, приостановлено 3ms + 14ms
01-25 16: 10: 15.372: I/dalvikvm-heap (21578): Захват целевой GC-кучи от 52.979MB до 48.000MB
01-25 16: 10: 15.382: D/dalvikvm (21578): GC_CONCURRENT освобожден 2273K, 5% бесплатно 46815K/49187K, приостановлено 3ms + 15ms
01-25 16: 10: 15.622: I/dalvikvm-heap (21578): Clam p target GC heap от 52.604MB до 48.000MB
01-25 16: 10: 15.622: D/dalvikvm (21578): GC_FOR_ALLOC освобожден 657K, 6% бесплатно 46431K/49187K, приостановлено 202 мс
01-25 16:10: 16.203: I/dalvikvm-heap (21578): Захват целевой GC-кучи от 52.959MB до 48.000MB
01-25 16: 10: 16.203: D/dalvikvm (21578): GC_FOR_ALLOC освобожден 1469K, 5% бесплатно 46796K/49187K, приостановлено 217 мс
01-25 16: 10: 16.203: I/dalvikvm-heap (21578): принудительная сборка SoftReferences для выделения 278744 байтов
01-25 16: 10: 16.423: I/dalvikvm-heap (21578) : Захват целевой GC-кучи от 52.952MB до 48.000MB
01-25 16: 10: 16.423: D/dalvikvm (21578): GC_BEFORE_OOM освобожден 9K, 5% бесплатно 46786K/49187K, приостановлено 219ms
01-25 16: 10: 16.423: E/dalvikvm-heap (21578): Недостаточно памяти при распределении 278744 байта.

Любые предложения/помощь будут оценены.

+0

Используйте MAT для определения источника утечки. – CommonsWare

+1

Использование MAT, а затем поиск объекта с самым большим сохраненным размером (который продолжает расти с каждым циклом), а затем используя путь к корням GC, исключая слабые ссылки, я достиг следующего: class maps.by.a @ 0x414f7fa8 System Class. - Но я не знаю, что делать дальше. – Nims

+1

Кажется, что что-то накапливается в Hashmap: класс «maps.by.a», загруженный «dalvik.system.PathClassLoader @ 0x413de740», занимает 12,923,112 (57,78%) байт. Память накапливается в одном экземпляре «java.util.HashMap $ HashMapEntry []», загружаемом «<загрузчик системного класса>». Ключевые слова java.util.HashMap $ HashMapEntry [] maps.by.a dalvik.system.PathClassLoader @ 0x413de740 – Nims

ответ

0

Используйте это в макете:

<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> 

И этот код:

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

свой полный код –

+0

@SinghArjun, что полный код – Marckaraujo

+0

Что ДРЕВЕСИНЫ здесь LatLngBounds границы = новый LatLngBounds.Builder() .include (Woods) и имя переменной для mUiSettings –

7

Насколько я могу сказать от некоторых основных MAT слежки, что вы видите, является кэшем поддерживаемый Maps V2 загруженных данных карты. Кажется, что кеш больше, если вы увеличиваете масштаб и увеличиваете масштаб. Кэш сжимается, если вы покинете карту и позже вернетесь к новой карте.Я не мог получить N кэшей из N раз, запуская активность карты вашего примера приложения, а размер кеша отбрасывался и протекал в зависимости от того, что сделал пользователь.

Увы, этот кэш unconfigurable, AFAIK, в плане того, как он велик, когда он получает убрался, она перекинется на диск и т.д.

Таким образом, по умолчанию, все, что вы можете сделать оставьте в стороне здоровый кусок вашего пространства кучи для Maps V2, чтобы играть с ним, и предпринимайте шаги, чтобы остаться в этом меньшем подмножестве кучи.

Если вы хотите поэкспериментировать, можно попробовать вызвать clear() на GoogleMap или onLowMemory() на вашем SupportMapFragment, чтобы увидеть, если какой-либо помочь уменьшить этот размер кэша.

+0

Хотя некоторые из наблюдаемых действий могут быть связаны с кэшированием ebb и flow, фрагмент карт определенно протекает в контексте его размещения. Это можно легко проверить, несколько раз вращая деятельность с картой, а затем видя, сколько копий активности все еще находится в куче. Даже демонстрационное приложение для карт делает это, как описано в [отчете об ошибке] (http://code.google.com/p/gmaps-api-issues/issues/detail?id=4766). – blahdiblah

1

У меня точно такая же проблема. Память увеличивается каждый раз, когда начинается работа, на которой размещается карта V2. И он не освобождается, даже когда деятельность заканчивается.

Таким обходным путем является повторное использование этой активности. Сделайте свою деятельность singleTask в манифесте, и вместо него finish() используйте moveTaskToBack(true);

+0

Это хорошее решение, если у вас есть только одна карта или очень мало карт, но я не вижу, как это будет работать, если у вас есть карты в нескольких действиях. – Nims

+0

нет его не работает –