userM1433372
userM1433372

Reputation: 5487

75 markers on Map -> memory leaks -> OutOfMemoryException

I've got a problem with drawing approximately 80 markers on a Google Map. I'm using Google Maps Android API v2.

The icons of the markers are dynamic (change in time). After adding a marker to the map it is not possible to change the icon. Therefor I have to remove all markers and add all markers again.

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

After executing this code multiple times (it is refreshed once per minute) I get an OutOfMemoryExpcetion.

When using larger markers icon the OutOfMemoryException is throw faster so I think the memory problem is related to the icon bitmap which is not recycled properly.

I also figured out that when changing the rotation of the device from landscape to portait and back increases the heap memory used. After a GC the memory is not freed.

Does someone know whether I'm adding the markers incorrectly or am I facing a problem in the Map API implementation?


I tried to reproduce the error with the Google Map sample application. In android-sdk/extras/google/google_play_services/samples/maps/src/com/example/mapdemo/MarkerDemoActivity.java a marker demo can be found. The speed up the testing I increased the numbers of markers created.

int numMarkersInRainbow = 12;

change to

int numMarkersInRainbow = 100;

Now start the demo App, select the markers demo and switch the rotation of your device from portrait to landscape and back a few times.

Initial heap:

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

Heap after a few orientation changes:

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

Heap after a few more orientation changes:

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

The end result will be an OutOfMemoryExcpetion.

A heap dump shows some possible heap leaks: https://www.box.com/s/rsy0k22dcp267se2g1fy

The full heap dump: https://www.box.com/s/6lyv2p6rlc0njqxw5zgu

Update: It seems to be related to an memory leaking issue in Android Maps V2. See https://code.google.com/p/gmaps-api-issues/issues/detail?id=4766 According to the issue is should be fixed but i did not tested it myself.

Upvotes: 13

Views: 3232

Answers (3)

apenasVB
apenasVB

Reputation: 1463

Whenever I have memory leak issues on my apps, I go through the following scenario

  1. Load the app
  2. Perform the operation that is suspected of leaking memory (preferably more than one time, so it's easier to analyze afterwards)
  3. Finish the app (pressing back until it returns to main screen)
  4. Analyse the memory dump

The steps I use for my analysis are

  1. Open Histogram
  2. Search for my package name
  3. Check if there are any references that should not be

If there are leaks and you repeated the leaky operation multiple times, you will see multiple instances of fragments, activities, views, etc. In order to identify the leak culprit:

  1. Right-click on a leaked object -> List objects -> with incoming reference
  2. Choose one of the incoming references, right click -> Path to GC roots -> exclude WeakReferences
  3. Open the stack levels until you identify a reference. If the only path leads to a Finalizer, you dug too deep. If it was inconclusive, try another leaked object, repeat steps.

Sorry it is not an exact science, but it will lead to hints that will enable you to identify the leaky code more easily.

Upvotes: 0

vkinra
vkinra

Reputation: 943

Yes, you are facing a very classic and common problem that plagues a lot of Android developers..the menacing OOM. The issue happens when you are not completely cleaning up your old drawables on update or rotation. To fix you really should iterate through your markers before mMap.clear and setting them to null, and possibly requesting (you can't force it) garbage collection by calling System.gc().

Upvotes: 1

Don Cowan
Don Cowan

Reputation: 1

Here's one approach you might take as a workaround to a possible API issue ... detect a device rotation and delete the MarketOptions object by setting it to null ... then re-fill it with your markers.

Upvotes: 0

Related Questions