android内存泄漏

参考:http://www.iwfu.me/2016/08/02/%E5%AE%89%E5%8D%93%E9%9D%A2%E8%AF%95%E9%A2%98-5-%E5%85%B3%E4%BA%8E%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F/
什么是内存泄漏
内存泄露,简单的说,就是该被释放的内存没有被释放,一直被某个或某些实例所引用但不能被使用,导致GC不能回收,造成内存泄漏。总结的说,可以理解为长生命周期的对象一直持有短生命周期对象的引用,导致短生命周期对象一直被引用而无法被GC回收,内存泄漏是造成OOM的主要原因之一,当一个应用中产生的内存泄漏比较多时,就难免会导致应用所需要的内存超过这个系统分配的内存限额,这就造成了内存溢出而导致应用Crash。。

安卓中常见的内存泄漏场景
1.单例造成内存泄漏
因为单例模式有其静态的特点,其生命周期和应用一样长,如果单例对象中包含了一个其他对象的引用,那么即使这个对象不再使用,依然存在一个单例对象引用它,造成无法回收。比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context;
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}
这个单例对象包含了一个Context的引用,所以此时要考虑,

如果传入一个Application Context,它的生命周期和应用一样长,没问题。
如果传入一个Activity Context,Activity退出销毁但任然被单例所引用了,会导致内存泄漏。
所以正确的单例应该修改为下面这种方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AppManager {
private static AppManager instance;
private Context context;
private AppManager(Context context) {
this.context = context.getApplicationContext();
}
public static AppManager getInstance(Context context) {
if (instance != null) {
instance = new AppManager(context);
}
return instance;
}
}

2.非静态内部类创建其静态实例造成内存泄漏
有的时候我们可能会在启动频繁的Activity中,为了避免重复创建相同的数据资源,会出现这种写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends AppCompatActivity {
private static TestResource mResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mManager == null){
mManager = new TestResource();
}
//…
}
class TestResource {
//…
}
}
这样就在Activity内部创建了一个非静态内部类的单例,每次启动Activity时都会使用该单例的数据,这样虽然避免了资源的重复创建,不过这种写法却会造成内存泄漏,因为非静态内部类默认会持有外部类的引用,而又使用了该非静态内部类创建了一个静态的实例,该实例的生命周期和应用的一样长,这就导致了该静态实例一直会持有该Activity的引用,导致Activity的内存资源不能正常回收。正确的做法为:

将该内部类设为静态内部类或将该内部类抽取出来封装成一个单例,如果需要使用Context,请使用Application Context 。

3.匿名内部类/异步线程造成内存泄漏
如下这两个示例可能每个人都这样写过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//——————test1
new AsyncTask

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值