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.

  • Set title background color
  • How come that a camera preview in a textureview is much more fuzzy than in a surfaceview?
  • Android Color Drawable Resource
  • How to catch a soft keyboard 'enter/done' press?
  • SDK Manager is missing older Android System images for emulator
  • How do change the font size and font color from a Java file?
  • 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.

    Related posts:

    Android: Parcelable.writeToParcel and Parcelable.Creator.createFromParcel are never called
    Android: Passing data from child fragment to parent fragment
    Build works in debug, fails in release - ZipException duplicate entry
    Fragment design: Adapting to multiple screen layouts by showing/hiding fragments within a single Act...
    &lt;? extends A&gt; won&#039;t accept A&#039;s child classes
    How to remove all notifications when an android app (activity or service) is killed?
  • Recording video using MediaRecorder and FileOutputStream produces video file that can't be played
  • Determine whether JSON is a JSONObject or JSONArray
  • Running Ionic at cca throw “Cannot read property 'Keyboard' of undefined” @ app.js:14
  • Android L is ignoring shapes as drawable background
  • Dismiss AlertDialog.Builder from OnClick
  • Cannot resolve constructor ArrayAdapter
  • 3 Solutions collect form web for “75 markers on Map -> memory leaks -> OutOfMemoryException”

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

    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.

    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.

    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.