我有两个活动,都有一个内部类SurfaceView,它有一个内部类Thread。第一个是菜单屏幕,第二个是比赛屏幕,用于比赛。
要从第一个开始第二个活动,我这样做:
Intent intent = new Intent();
intent.setClass(Menu.this, RaceActivity.class);
intent.putExtra("level", level.getNumber());
startActivityForResult(intent, 0);
当关卡完成后,从我运行的第二个活动开始。
finish();
这会调用我的onDestroy方法。我认为这足以让我的第二个活动可以进行垃圾收集。但是当我完成比赛并多次开始新的比赛时,我注意到最终我会崩溃。在Eclipse中使用Memory Analyzer Tool(MAT)我发现很多对我的第二个Activity的引用,而SurfaceView和Thread仍然被保留。所以我也决定用destroy方法清理那些。
public void onDestroy() {
super.onDestroy();
mPanel.mThread.destroy(); //destroys surfaceholder in thread
mPanel.mThread = null;
mPanel = null;
}
这似乎几乎消除了一切。但是当我进入MAT时,我仍然看到第二个活动的一个参考(当选择GC根路径时 - >排除弱引用)
Class Name | Shallow Heap | Retained Heap
---------------------------------------------------------------------------
com.moz.by.RaceActivity @ 0x405b6108 Unknown| 280 | 8,008
---------------------------------------------------------------------------
这是我尝试使用GC的Activity的名称,因此它似乎在某个地方持有对其自身的引用。这个或Unknown关键字在这里有一些意义。
我对这个问题感到困惑,因为我不确定下一步该去找哪个。我想知道我是否能找到错误,这个活动最终会清理干净!现在已经坚持了几天,所以我想我会彻底向好人解释我的问题。有人可能会建议我可能犯的初学者错误。
感谢阅读。
P.S。这是我的第一个应用程序道歉,如果我错过了我的工作流程中的基本内容。在我开始并结束几场比赛之后,下面是来自MAT的dominator_tree的一部分。
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%
------------------------------------------------------------------------------------------------------------------
编辑:
所以似乎对RaceActivity的最后一个引用是在内部内部类TutorialThread中,它似乎在这个$ 0变量中持有对类的引用。见下文。
Type |Name |Value
-----------------------------------------------------------
ref |this$0 |com.moz.by.RaceActivity @ 0x4053b080
ref |mSurfaceHolder|null
ref |mPanel |null
boolean|mRun |false
-----------------------------------------------------------
我不确定为什么会这样,这就是我结束我的线索的方式。
boolean retry = true;
mThread.setRunning(false);
while (retry) {
try {
mThread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我认为这应该结束线程,但它永远不会得到GC,因为奇怪的这个$ 0变量的最终引用。任何人都知道这个变量是什么以及如何清除它?
答案 0 :(得分:2)
你喜欢这个活动,可能是因为你得到了一些静态引用,或者你有一些如何将它传递给下一个活动。
顺便说一句,当你停止线程时,你是这样做的吗?
Thread myThread = new Thread();
try {
myThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
myThread = null;
你应该。