欢迎使用CSDN-markdown编辑器
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了欢迎使用CSDN-markdown编辑器,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2532字,纯文字阅读大概需要4分钟。
内容图文
内存泄漏介绍
内存泄漏是针对与堆内存而言的。
Java的内存管理就是对象的分配和释放。内存分配是由程序进行的,内存的释放是由GC完成。GC只能回收那些无用,且不被其他对象引用的对象们占用的空间。
从Main方法开始延伸,所有可以到达的对象都是有效对象,组成对象集合,这些不能被回收。其他的孤立对象则是GC回收的目标。
{
Object o = newObject();
}
局部变量的生命周期是在大括号结束。这时候,栈内的o被销毁,则 new Object() 这个对象不在被引用,成为孤立对象,会被GC回收。
所以,内存泄漏的根本原因是:堆内存中的长生命周期的对象持有短生命周期对象的强/软引用,尽管短生命周期对象已经不再需要,但因为长生命周期对象持有对他的引用而导致他不能被回收。
常见的内存泄漏
-
集合
集合如果只有添加方法,没有删除方法,内存会被大量占用。如果集合是全局的,会造成内存只增不减。
-
单例
单例对象在被初始化后会在JVM整个生命周期中存在,如果单例持有了外部对象,会造成外部对象不能被回收,致使内存泄漏。
public
class Test{
privatestatic Test test;
private Context context;
privateTest(Context context){
this.context = context;
}
publicstatic Test getInstance(Context context){
if(test == null){
test = new Test(context);
}
return test;
}
}
如果传入的context是一个activity,会使activity一直存在于内存中,不能被释放。
-
Android中的各种组件
BroadCastReceiver,ContentObserver,Cursor等,在Regist后,记得在结束时调用unRegister或close(),并且,不要将Activity作为成员变量使用,例如上面单例的使用。如果一定需要,则记得使用 WeakReference。
-
非静态内部类
public
class
MainActivity
extends
AppCompatActivity {
private
static TestResource mResource = null;
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mResource == null){
mResource = new TestResource();
}
//...
}
class TestResource {
//...
}
}
外部类的静态成员mResource的生命周期是整个程序的运行时间,而内部类的对象默认持有对外部类对象的一个引用,所以会导致Activity无法得到释放。
可以将内部类定义为静态内部类,则可以将内部类和外部类的对象的关系切断,只与类有关。
-
线程造成的内存泄漏
因为线程的生命周期不可控,如果线程保存了对外部对象的引用,会造成外部对象的不可释放。
-
Handler造成的内存泄漏
如果handler发送的message没有被处理,那么MessageQueue将一直保留对handler,message的引用,而且handler与Activity的生命周期并不一致,可能会导致activity不能顺利释放。
public
class
SampleActivity
extends
Activity {
private
final Handler mLeakyHandler = new Handler() {
@OverridepublicvoidhandleMessage(Message msg) {
// ...
}
}
@OverrideprotectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Post a message and delay its execution for 10 minutes.
mLeakyHandler.postDelayed(new Runnable() {
@Overridepublicvoidrun() { /* ... */ }
}, 1000 * 60 * 10);
// Go back to the previous Activity.
finish();
}
}
以上代码,发送了延时的消息,这消息并未被处理时,该页面退出会导致该页面无法被回收。
注意事项
- 对activity的引用要考虑activity的生命周期,不过不能控制在其生命周期内,可以考虑用getApplicationContext(),避免activity长时间被占用。
- 尽量不要在静态内部类使用非静态的成员变量,必须要用,也要在适当的时候将其置为空;也可以在静态内部类中使用弱引用来引用外部成员变量。
- Handler持有的引用对象最好为弱引用,资源释放的时候可以清空handler中的消息。
- 线程处理耗时操作,在页面返回时即使取消。
原文:http://blog.csdn.net/sj18271633329/article/details/51331839
内容总结
以上是互联网集市为您收集整理的欢迎使用CSDN-markdown编辑器全部内容,希望文章能够帮你解决欢迎使用CSDN-markdown编辑器所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。