Android 常见内存泄漏总结、避免踩坑、提供解决方案。

本文详细讲述了Android开发中常见的内存泄漏问题,如匿名内部类导致的对象持有、Handler和Message的内存管理、Context和View的生命周期、大对象和监听器的释放,以及资源对象的正确关闭。提供了解决这些问题的方案和注意事项。
摘要由CSDN通过智能技术生成

}

});

threadPoolExecutor.submit(new Runnable() {

@Override

public void run() {

while (true){

Log.d(“TAG”, “run: test”);

}

}

});

}

});

}

}

点击button执行线程任务,提交了一个runable进去,因为里面死循环永远不会结束。所以匿名内部类会一直持有TestActivitty对象。不会被系统回收掉😮。因为匿名内部类这玩意进场使用,所以还是需要注意的!!!🤦‍♀️

解决方案🙆‍♀️

  • 将匿名内部类/非静态内部类替换成静态内部类,因为静态内部类不会持有外部类的引用

  • 一定要用匿名内部类/非静态内部类的话,要保证内部类的生命周期短于外部类

Handle内存泄漏


描述🤦‍♀️

这个就有点老生常谈了😂,但还是的说一下。

Handler发送的Message会存储在MessageQueue里面,但是他们不一定马上就被处理了。

另外我们知道Message的Target会持有记录当前的Handler对象,用于进行消息分发。所以如果Message不被及时处理,那么Handler就无法被回收。

那么如果此时Handler是非静态的,则Handler也会导致引用它的Activity不能被回收😮。

举个例子🌰

public class TestActivity extends AppCompatActivity {

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.item_layout);

Handler mHandler = new Handler(){

@Override

public void handleMessage(Message msg) {

super.handleMessage(msg);

}

};

findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

mHandler.sendMessageDelayed(new Message(),100000);

finish();

}

});

}

}

当点击button时,会finish当前activity。但是因为消息没有被及时处理,间接引用了Handler对象,Handler又是匿名内部类实例,持有了activity对象。所以导致内存泄漏🤦‍♀️。

解决方案🙆‍♀️

  • 使用静态Handler内部类,handler的持有者用弱引用。

  • 在onDestroy中将未执行的消息和Callbacks清除。

if (mHandler != null) {

mHandler.removeCallbacksAndMessages(null);

}

Context被长期持有


描述🤦‍♀️

这个也很简单,比如你把Activity的Context传给了一个长期存在的对象,那其实activity的context就是它自身,那么因为被持有就回收不了。造成内存泄漏

解决方案🙆‍♀️

  • 对于不是必须使用Activity的Context的情况(Dialog的Context必须使用Activity的Context),可以考虑使用Application来代替Activity的Context,因为一般使用Context无非时获取一些资源而已。

  • 一定要传入Activity的Context的话,一定要注意生命周期,不可以被长期引用。

View被静态修饰


描述🤦‍♀️

这个。。。。我估计没有多少人这么使用吧。如果View被静态修饰的话,因为View会持有Context,所以就会导致当前Activity不会被回收。🤦‍♀️

举个例子🌰

public class TestActivity extends AppCompatActivity {

static View button;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.item_layout);

button = findViewById(R.id.button);

}

}

解决方案🙆‍♀️

  • 在onDestory中将view置null。

大对象/监听器释放


描述🤦‍♀️

大对象比如Bitmap

Bitmap对象一般比较大,而且好多操作都需要变换产生新的对象。所以需要注意一定要尽快释放临时的Bitmap对象用于节省内存。尽量避免被静态修饰或者其他长生命周期引用。

监听器的释放

很多服务需要register和unregister监听器,需要在合适的时候及时的unregister这些监听器否则容易产生内存泄漏。

解决方案🙆‍♀️

  • 大对象及时释放

  • 监听器在合适的时候进行释放

资源对象注意关闭


描述🤦‍♀️

资源对象比如File、Cursor等,如果不进行正常关闭,会造成内存泄漏。

解决方案🙆‍♀️

  • 通常使用异常代码块捕获,在finally语句中进行关闭,防止出现异常资源没有被正常释放问题。

集合对象


描述🤦‍♀️

注意一些生命周期很长的集合,比如被static修饰的集合,它的生命周期会时APP的生命周期,那么它里面维持的对象,如果在没用之后要即使清理掉,否则就会造成内存泄漏。

举个例子🌰

public class TestActivity extends AppCompatActivity {

static List vies;

最后我还整理了很多Android中高级的PDF技术文档。以及一些大厂面试真题解析文档。

image

Android高级架构师之路很漫长,一起共勉吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

。以及一些大厂面试真题解析文档。**

[外链图片转存中…(img-1UTtTvFB-1714190132859)]

Android高级架构师之路很漫长,一起共勉吧!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值