【发布时间】:2011-12-09 01:11:09
【问题描述】:
我最近了解到泄漏上下文会浪费多少内存,以及如何在屏幕方向更改后使用内存转储来测试此类泄漏。新的活动应该被实例化和创建,原来的活动应该被销毁和收集。但是,除非我正在泄漏内存并且看不到它,否则如果下面的 Activity 启动不同的 Activity 并自行销毁,则似乎不会被收集:
public class Foo extends Activity {
private Button button;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button = new Button(this);
button.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
startActivity(new Intent(Foo.this, Bar.class));
finish();
}
});
setContentView(button);
}
protected void onDestroy() {
super.onDestroy();
button.setOnClickListener(null);
Log.e("you're it", "isFinishing() == " + isFinishing());
}
}
public class Bar extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setText("hello, world");
setContentView(textView);
}
}
这是内存转储信息,在单击按钮启动 Bar 并请求垃圾收集几次后获取:
Class Name | Shallow Heap | Retained Heap
----------------------------------------------------------------------------------------
com.test.testProject.Foo @ 0x4135b188 | 184 | 2,208
mOuterContext android.app.ContextImpl @ 0x4135b390 | 96 | 392
<Java Local> java.lang.Thread @ 0x40996460 main Thread| 80 | 1,416
mContext android.media.AudioManager @ 0x4135b480 | 48 | 176
----------------------------------------------------------------------------------------
基于this,我认为在活动之间进行额外的完成将使第一个有资格收集并允许我以另一种方式测试泄漏,这是否明智?我在泄漏内存吗? Android 是否有某些原因想要保留这个被破坏的活动?
【问题讨论】:
-
您没有泄漏内存。我相信 GC 还没有决定清理活动 - 即使您已请求垃圾收集。你在哪个版本的android上测试它?我想如果你在 3.0+ 上尝试同样的事情,GC 会更快地删除它
-
也许在分析转储文件时检查
Intent对象仍然处于活动状态。它可能会指向 Foo 和 Bar。 -
这是4.0平台的。此外,还有两个 Intent 实例,一个被 Foo 引用,一个被 Bar 引用。我认为这是有道理的,因为每个 Activity 都有一个对 getIntent() 的 Intent 的引用。保持 Activity 活着的不是 Intent,不是吗?
-
在开发选项中,您可以设置一个名为“不保留活动”的标志,看看这是否有帮助,如果没有,那么我将进行更深入的研究,因为没有什么东西会泄露给我。可能只是还没有 gcd
-
调用 'finish()' 将导致 onDestory() 回调。这意味着你的活动已经完成,应该关闭......
标签: android testing memory-leaks lifecycle