2013-01-06 19 views
12

Mam problem z rysowaniem około 80 znaczników na mapie Google. Używam Google Maps Android API v2.75 znaczników na mapie -> wycieki pamięci -> OutOfMemoryException

Ikony znaczników są dynamiczne (zmiana w czasie). Po dodaniu znacznika do mapy nie można zmienić ikony. Dlatego muszę usunąć wszystkie znaczniki i ponownie dodać wszystkie znaczniki.

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

Po wykonaniu tego kodu kilka razy (to jest odświeżany co minutę) otrzymuję OutOfMemoryExpcetion.

Podczas korzystania z większych znaczników ikona OutOfMemoryException jest rzucana szybciej, więc myślę, że problem z pamięcią jest związany z mapą bitową ikony, która nie jest prawidłowo przetwarzana.

Ja również zorientowali się, że przy zmianie obrót urządzenia z góry iz powrotem do Portait zwiększa pamięć sterty używany. Po GC pamięć nie jest zwalniana.

Czy ktoś wie, czy Dodaję znaczniki nieprawidłowo albo ja w obliczu problemu w realizacji Map API?


Starałem się odtworzyć błąd z przykładowej aplikacji Google Map. W android-sdk/extras/google/google_play_services/samples/maps/src/com/example/mapdemo/MarkerDemoActivity.java można znaleźć demo znacznika. Przyspieszenie testów zwiększyło liczbę utworzonych znaczników.

int numMarkersInRainbow = 12; 

zmiana

int numMarkersInRainbow = 100; 

Teraz uruchomić demo aplikacji, wybierz znaczniki demo i przełączyć obrót urządzenia z pionowej na poziomą i z powrotem kilka razy.

sterty początkowa:

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

sterty po kilku orientacji zmienia:

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

sterty po kilku kolejnych zmian orientacji:

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

końcowy będzie OutOfMemoryExcpetion .

Sterta zrzut pokazuje kilka możliwych przecieków sterty: https://www.box.com/s/rsy0k22dcp267se2g1fy

Pełny zrzut stosu: https://www.box.com/s/6lyv2p6rlc0njqxw5zgu

Aktualizacja: wydaje się być związane z pamięci wyciekające problemu w Android Maps V2. Zobacz https://code.google.com/p/gmaps-api-issues/issues/detail?id=4766 Zgodnie z problemem należy go naprawić, ale sam go nie przetestowałem.

+0

Ten artykuł bardzo Ci pomoże, jeśli go przeczytasz i podejmiesz odpowiednie działania: http://developer.android.com/training/displaying-bitmaps/index.html –

+3

Andy: Dzięki za wskazówkę. Nie zarządzam samoczynnym ładowaniem bitmapy. To kod Google Maps ładuje mapy bitowe. Dostarczam tylko zasób do rysowania. Próbowałem załadować sam dół map bitowych, ale wciąż miałem te same problemy. (moje znaczniki jako 2-3kb) – userM1433372

+0

Istnieje kilka problemów z wyciekiem w nowym interfejsie API. Miejmy nadzieję, że wkrótce zostaną naprawione. – Warpzit

Odpowiedz

0

Oto jedno podejście można przyjąć jako obejście do ewentualnej emisji API ... wykrywa obrót urządzenia i usunąć MarketOptions obiektu poprzez ustawienie go na null ... następnie ponownie napełnić go swoimi markerami.

+0

Dzięki. Próbowałem twojego podejścia. Niestety nie rozwiązuje problemu. Niwelując MarketOptions, rysunki nie są zwalniane. – userM1433372

1

Tak, masz do czynienia z bardzo klasyczny i wspólny problem dręczy wiele Androida developers..the groźny OOM.Problem pojawia się, gdy nie usuwasz całkowicie starych rysunków po aktualizacji lub rotacji. Naprawdę, naprawdę powinieneś przetestować swoje znaczniki przed mMap.clear i ustawić je na wartość null, a także ewentualnie zażądać (nie możesz wymusić) wyrzucania śmieci przez wywołanie System.gc().

+1

Niestety, rysunki są tworzone przez interfejs API Map Google i są całkowicie ukryte, więc nie mogę ich anulować. – userM1433372

+0

Zawsze możesz zachować odniesienie do swoich obiektów Markera w zmiennej ArrayList i dodać każdy znacznik do niej, gdy początkowo zapełniasz mapę i tworzysz znaczniki. Następnie możesz powtórzyć całą tablicę i wyzerować każdy znacznik, zgodnie z sugestią zawartą w odpowiedzi. –

0

Ilekroć mam problemy wyciek pamięci na mojej aplikacji, idę poprzez następujący scenariusz

  1. Załaduj aplikacja
  2. wykonać operację, która jest podejrzany o wyciek pamięci (najlepiej więcej niż jeden raz, więc jest to łatwiej analizować później)
  3. Zakończ aplikację (tłoczenie z powrotem, aż powróci do ekranu głównego)
  4. analizować pamięć zrzucić

Kroki używam dla mojej analizy są

  1. Otwarte Histogram
  2. Szukaj mojej nazwy pakietu
  3. Sprawdź, czy są jakieś wzmianki, że nie powinno być

Jeśli istnieją przecieki i Powtórzyłeś tę nieszczelną operację wiele razy, zobaczysz wiele instancji fragmentów, działań, widoków itp. Aby zidentyfikować sprawcę wycieku:

  1. kliknij prawym przyciskiem myszy na wyciekły obiektu -> Przedmioty Lista -> w odniesieniu przychodzącego
  2. wybrać jeden z odnośników przychodzących, kliknij prawym przyciskiem -> Ścieżka do GC korzenie -> wykluczyć WeakReferences
  3. otworzyć poziomy stosu aż do ciebie zidentyfikować odniesienie. Jeśli jedyna ścieżka prowadzi do Finalizera, przekopałeś się zbyt głęboko. Jeśli nie było to jednoznaczne, spróbuj użyć innego przecieku, powtórz kroki.

Niestety nie jest to nauka ścisła, ale prowadzi do wskazówek, które pozwolą łatwiej zidentyfikować nieszczelny kod.