现在我们需要分析是哪一个引用到了,导致没有被回收
public class MainActivity extends Activity implements OnClickListener {
public ArrayList<Object> list = new ArrayList<Object>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(this, SubActivity.class);
startActivity(intent);
}
}
启动SubActivity.class
public class LeakDemo {
private static LeakDemo sefl;// 这里面是一个典型的单例模式,这里面会长驻在内存中,这里面出现的一个错误也,就是在saveData里面使用了context
// 现在我们使一个插件memcry analyzer下载地址:http://www.eclipse.org/mat/downloads.php
private Context ctx;
public LeakDemo(Context ctx) {
this.ctx = ctx;
}
public static LeakDemo getInstane(Context context) {
if (sefl == null) {
sefl = new LeakDemo(context);
}
return sefl;
}
public void saveData() {
ctx.getSharedPreferences("", 0);
}
}
//
public class SubActivity extends Activity implements OnClickListener {
public ArrayList<Object> list = new ArrayList<Object>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 如果发生泄洪的不是actiivty,那么我们怎么来查找到它昵,现在我们来测试一个泄漏的对象
// 现在我们来做一下测试,我们还是以泄露为手段但是 我们调试的手机并不只是针对activity
// 现在我们生成了.hprof,我们再点击overview,然后再找到histogram,这个表示你当前应用进程被人引用的部份,这些都是不能被gc掉的
// 现在我们怎么定位我们的变量也,这里面可以在histogram最上面输入包名进行过滤,现在我们可以看到有两个,一个是SubActiivty,一个是LeakDemo,这个时候我们的SubActivity已经返回了
// 但是还是没有被回收这个时候你就要对自己的程序有一个把控了,那些应该被释放,那些不应该被释放,SubActivity很可一,被人引用关,且没有被释放,而LeakDemo不一样,我们在设计上就使用static的
// 所以它不被解引用是很正常的,但SubActiivty,我按返回了应该被释放
// 这时候我们怎么查看应该被释放而没有释放的也,然后我们在应该释放而没有释放的类上点击右键,点击merge shortest path to gc roots 然后再点击(我们这里面只关心强引用)
// weak/soft就可以查看,这里面就可以查看了,ctx变量引起的,这就一个简单的演示,通过mat
// 这里面还是有一定要求的,首先你确认发送了内存泄漏,首页是前面那张表中那些应该被释放被释放,下面我们来看一下handler造成的内存泄漏oom3_4
}
@Override
public void onClick(View v) {
Toast.makeText(this, "onclick", 0).show();
LeakDemo.getInstane(this).saveData();
}
}