1

I have written a mapping application which can either use Google Maps or Open Street Map as a tile provider. The Google and OSM maps are displayed in separate activities. After the splash screen a select mode activity is entered. From this screen the user can either choose the Google or OSM activty via a button.

I'd like to be able to switch between Google and OSM via a button in each mapping activity. When I code the click handler for each of the mapping activities, I have in each:

i = new Intent("com.me.otheractivity");
finish();
startActivity(i);

I have no service connection, or inner classes for overlays etc. anywhere in the code. When I traverse from Select->Google-> Select(via back button) -> OSM , all is fine in terms of allocated heap.

If I go directly from one mapping activity to the other repeatedly, then the allocated heap grows and eventually crashes at 16M. Obviously it must be leaking somewhere via this route.

I'm logging every onCreate, Start, Resume, Pause, Stop and Destroy in all 3 activities. If I use the back button route I have the log:

Select Activity -> Google Activity -> OSM Activity (direct via button in Google Activity)

Select Activity Pause 
Google Activity Create
Google Activity Start 
Google Activity Resume
Select Activity Stop 
Google Activity Pause 
Open SM Activity Create 
Open SM Activity Start 
Open SM Activity Resume 
Google Activity Stop 
Google Activity Destroy

Going via back button, I get

Select Activity -> Google Activity -> Select Activity -> OSM (via back button)

Select Activity Pause 
Google Activity Create 
Google Activity Start
Google Activity Resume 
Select Activity Stop
Google Activity Pause 
Select Activity Start 
Select Activity Resume 
Google Activity Stop 
Google Activity Destroy
Select Activity Pause
Open SM Activity Create
Open SM Activity Start
Open SM Activity Resume
Select Activity Stop 

In the first example the Google Activity is not stopped or destroyed until after the OSM one is created, started and resumed. Is this significant regarding the leak?

I set to null all timers, handlers and overlays in the onPauses. (Combining the two views in one activity is not really an option owing to the differences between the Google maps.jar and osmdroid.jar)

Is anything wrong with the code in my click handlers?

All suggestions will be gratefully received.

EDIT 26th Feb

Further to my original post - the salient point for me is :

Why is it necessary for the onDestroy in one activity to run before the onResume in the second activity for the memory usage to stop growing?

If the onResume in activity B runs before the onDestroy in activity A, then I see that the number of activities on the history stack (as reported by adb shell dumpsys meminfo) increase by one each time. No amount of forced GC either in the code or via DDMS will take them off the stack.

I've since modified my code so that the clickhandler just calls finish(). In the onDestroy I call the startActivity(). This briefly returns the screen to the select mode activity before running the other activity. Under these circumstances obviously the onDestroy() in A runs before the onResume() in B and neither the history stack or heap usage grow.

I just don't get it.

NickT
  • 23,844
  • 11
  • 78
  • 121
  • We need more code in order to help. – Octavian Helm Feb 24 '11 at 22:14
  • I think I'd have to post the whole lot, which would be confusing, so I've tried to narrow the scope of my problem to the bare minimum. I'm really looking for an answer as why the exit via the clickHandler leaks, and exit via the back button doesn't? I.e is there something wrong with that finish() then startAcivity()? – NickT Feb 24 '11 at 22:34

3 Answers3

0

I would heavily recommend using the Eclipse MAT (Memory analyzer) tool against all android apps you plan to release.

I have noticed apps I have worked on ending up with memory leaks from patterns a standard java developer knows would not create a memory leak.

Use the MAT tool to trace the dependencies causing leaks and either rework that code or in worst case scenarios I have resorted to reflection to break the dependency and allow it to release.

Tyler Zale
  • 634
  • 1
  • 7
  • 23
  • I've used MAT. It just gives me 'suspects' of Strings and classes. I'd really like to get the suspects tried and either acquitted or found guilty, as in English law. MAT is giving me the verdict available in Scottish law of 'not proven'. – NickT Feb 24 '11 at 22:36
  • 1
    run your app for a bit and check out the histogram. Mash the garbage collector a few times before your dump the HPROF. That I find much more reliable to show what is still in memory rather than the suspects page which I find confusing at best. Anything still in memory which shouldn't be in memory is something to consider. (you can watch the adb logcat output to see when the garbage collector isnt releasing anything anymore when you hit the GC button, which means its done about all its going to do) – Tyler Zale Feb 24 '11 at 22:51
  • forgot to mention, in the histogram filter to your package to get rid of the mundane stuff you aren't worried about. Ex: com.myproject.* – Tyler Zale Feb 24 '11 at 22:54
0

You may be suffering from the same memory leak issue asked a few minutes in front of you here

Community
  • 1
  • 1
John J Smith
  • 11,435
  • 9
  • 53
  • 72
0

It relates to your code, as Octavian Damiean said, we need more information to help. I've tried your case with 3 simple Activities, no leak occurs. Every Activity instance destroyed can be successfully GCed. That means either there's a flaw in your application, or there's a flaw in the framework revealed by your application. In either case we need more than the descriptions you've provided.

But as you already know you're leaking "GoogleActivity" and "OpenSMActivity", MAT can be helpful.

Dump hprof file, click "Open Query Browser" (left to the search button) and then "Merge Shortest Paths to GC Roots" -> "exclude all phantom/weak/soft etc. references". Fill in the full class name of leaking Activity and finish. Then you'll see who's holding your Activity.

DenMark
  • 1,618
  • 1
  • 15
  • 16