I have two Activities, both have an inner class SurfaceView, which has an inner class Thread. The first is a menu screen and the second is a race screen where a game is played.
To start the second activity from the first I do this:
Intent intent = new Intent();
intent.setClass(Menu.this, RaceActivity.class);
intent.putExtra("level", level.getNumber());
startActivityForResult(intent, 0);
When the level is finished, from the second activity I run.
finish();
This calls my onDestroy method. I was under the impression this would be enough to make my 2nd activity elligble for garbage collection. But when I finish the race, and start a new race several times, I noticed eventually I would crash. Using the Memory Analyzer Tool (MAT) in Eclipse I found a lot of references to my 2nd Activity and the SurfaceView and the Thread were still being held. So I also decided to clean those up in the destroy method.
public void onDestroy() {
super.onDestroy();
mPanel.mThread.destroy(); //destroys surfaceholder in thread
mPanel.mThread = null;
mPanel = null;
}
This seems to have eliminated almost everything. But when I go into the MAT I still see one refence to the 2nd Activity (when choosing Path to GC Roots -> Exclude weak references)
Class Name | Shallow Heap | Retained Heap
---------------------------------------------------------------------------
com.moz.by.RaceActivity @ 0x405b6108 Unknown| 280 | 8,008
---------------------------------------------------------------------------
This is the name of the Activity I am trying to GC so it appears it is holding a reference to its self somewhere. Either that or the Unknown keyword has some significance here.
I am confused by the issue as I am not sure where to go next to look for this. I wonder if I can find whats wrong this Activity will finally clean up! Been stuck on this for a couple of days now so I thought I would thoroughly explained my issue to you good people. Someone may be able to suggest a beginners error I may have made.
Thanks for reading.
P.S. This is my first app apologises if I have missed something basic in my workflow. Below is a portion of the dominator_tree from MAT after I started and ended several races.
Class Name | Shallow Heap | Retained Heap | Percentage
------------------------------------------------------------------------------------------------------------------
com.moz.by.RaceActivity @ 0x405989e8 Unknown | 280 | 4,464 | 0.15%
com.moz.by.RaceActivity @ 0x405b6108 Unknown | 280 | 8,008 | 0.26%
com.moz.by.RaceActivity @ 0x406532e8 Unknown | 280 | 4,024 | 0.13%
com.moz.by.RaceActivity @ 0x4077f290 Unknown | 280 | 5,440 | 0.18%
com.moz.by.RaceActivity$Panel @ 0x40513d40 Unknown | 432 | 1,496 | 0.05%
com.moz.by.RaceActivity$Panel @ 0x40527148 Unknown | 432 | 1,496 | 0.05%
com.moz.by.RaceActivity$Panel @ 0x40653878 Unknown | 432 | 1,496 | 0.05%
com.moz.by.RaceActivity$Panel @ 0x40788490 Unknown | 432 | 1,496 | 0.05%
com.moz.by.RaceActivity$TutorialThread @ 0x40569580 Thread-35 | 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x40642558 Thread-37 Unknown| 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x40683108 Thread-59 Unknown| 120 | 120 | 0.00%
com.moz.by.RaceActivity$TutorialThread @ 0x406a56f0 Thread-57 | 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x40706f20 Thread-51 | 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x40707fe8 Thread-45 Unknown| 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x4077fa10 Thread-53 Unknown| 120 | 192 | 0.01%
com.moz.by.RaceActivity$TutorialThread @ 0x40789da0 Thread-43 | 120 | 192 | 0.01%
------------------------------------------------------------------------------------------------------------------
EDIT :
So it seems the last reference to the RaceActivity is in the inner inner class TutorialThread, where it appears to be holding a reference to the class in the this$0 variable. See below.
Type |Name |Value
-----------------------------------------------------------
ref |this$0 |com.moz.by.RaceActivity @ 0x4053b080
ref |mSurfaceHolder|null
ref |mPanel |null
boolean|mRun |false
-----------------------------------------------------------
I’m not sure why this is happening, this is how I am ending my thread.
boolean retry = true;
mThread.setRunning(false);
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I thought this should end the thread but it never gets GC’ed because of this final reference in the strange this$0 variable. Anyone know what this variable is and how I can clear it?
You are liking this activity, it may be because you got some static reference to it or you some how pass it to the next one.
By the way when you stop the thread are you doing it like this?
You should.