文章包括两部分:
(1)java内存泄漏基础知识
(2)Android内存泄漏。
一.Java内存泄漏基础知识
1.1 java内存分配策略:
在java程序运行中,
内存分配策略分为三个部分:静态分配,栈式分配,堆式分配。
对应的也分为三个内存存储区:静态存储区,栈区,堆区。
(1)静态存储区:也叫方法区,主要存放静态数据,全局变量,其中的变量在整个程序运行期间都存在。
(2)栈区:主要存放基本类型的变量和对象的引用变量,方法执行的时候,方法体内的局部变量会在栈中创建内存空间,并在方法结束后,变量持有的内存会自动运算,栈中内存空间容量有限。
(3)堆区:称为动态内存分配,通常就是new出来的对象存放在堆区,这部分内存在不使用的时候,由GC来管理。
1.2 Java是如何管理内存的
内存管理就是对象的分配和释放问题:
分配空间:在java中通过关键字new为对象申请内存空间,所有的对象都是在堆中分配空间的。
释放空间:是由GC垃圾回收器来自动管理的。
1.3 java中的内存泄漏
内存泄漏:是指无用的对象持续的占有内存,或无用的对象的内存得不到及时释放,从而造成内存空间的浪费,成为内存泄漏。
二.Android内存泄漏
2.1 单例模式引起的内存泄漏
造成原因:单例对象的静态特性使的单例对象生命周期与程序生命周期一样长,在使用单例模式使用context时使用的是activity的context,会导致在activity想要被回收的时候无法回收,造成内存泄漏。
解决办法:持有应用的 context。
2.2 非静态内部类默认持有外部类的引用
造成原因:在非静态内部类中有静态实例持有了外部类的引用,导致外部类无法被回收。
解决办法:将非静态内部类改为静态内部类,这样就不会持有外部类的引用,不会造成内存泄漏问题。
2.3 handler造成的内存泄漏
造成原因:创建的handler是非静态内部类,也会持有外部类的引用,在activity要被回收的时候还有未处理完的消息,造成内存泄漏。
解决办法:将handler写为静态内部类,并且持有外部类的弱引用。
2.4 尽量避免是使用static变量
造成原因:static变量生命周期与app生命周期一致
解决办法:尽量不使用static
2.5 资源为关闭造成的内存泄漏
造成原因:使用广播接受者,游标,bitmap的时候在activity要销毁的时候没有关闭或者注销,没有被回收造成泄漏。
解决办法:在activity要销毁的时候关闭或注销。
2.6 AsyncTask造成的内存泄漏
造成原因:非静态内部类持有外部类的引用,导致外部类无法回收。
解决办法:在activity的onDestroy中取消掉Asynctask
网友评论