Android活动永远不会导致内存不足异常

时间:2012-01-18 23:13:39

标签: java android memory garbage-collection

我有两个活动,都有一个内部类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变量的最终引用。任何人都知道这个变量是什么以及如何清除它?

1 个答案:

答案 0 :(得分:2)

你喜欢这个活动,可能是因为你得到了一些静态引用,或者你有一些如何将它传递给下一个活动。

顺便说一句,当你停止线程时,你是这样做的吗?

Thread myThread = new Thread();

        try {
            myThread.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        myThread = null;

你应该。