android内存泄漏问题

来源:互联网 发布:美国亚马逊数据分析 编辑:程序博客网 时间:2024/05/20 03:39

android的内存泄漏问题,在开发过程中可能会因为java的内存回收机制而忽略。

如果对象已经不再被使用,但是仍然有引用指向它,此时垃圾回收器是无法回收它的。此时,该对象占用的内存就无法被使用,造成了内存泄露。

Android的一个应用程序的内存泄漏对别的应用程序影响不是很大,为了能够是应用程序安全且快速的运行,android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行。并且android为不同类型的进程分配了内存上线,超过上限会被系统认为内存泄漏,进而kill掉此进程。不会影响其他进程。

如果是system_process等系统进程出问题,则会引起系统重启。

主要有以下几种情形的内存泄漏:

1.没有释放掉引用,造成的内存泄漏

1.1. 注册没有取消,造成的内存泄漏。第三方的Android程序,可能引用我们的Android程序的对象,例如:注册机制等。致使当前的Android程序已经结束了,但是由于引用程序的原因,造成内存泄漏,不能被及时回收。

    锁屏界面(LockScreen)中,监听系统中的电话服务以获取一些信息(如信号强度等),则可以在LockScreen 中定义一个 PhoneStateListener的对象,同时将它注册到 TelephonyManager服务中。对于 LockScreen对象,当需要显示锁屏界面的时候就会创建一个 LockScreen对象,而当锁屏界面消失的时候 LockScreen对象就会被释放掉。

但是如果在释放 LockScreen 对象的时候忘记取消我们之前注册的PhoneStateListener对象,则会导致 LockScreen无法被垃圾回收。如果不断的使锁屏界面显示和消失,则最终会由于大量的 LockScreen 对象没有办法被回收而引起OutOfMemory,使得system_process 进程挂掉。

  虽然有些系统程序,它本身好像是可以自动取消注册的(当然不及时),但是我们还是应该在我们的程序中明确的取消注册,程序结束时应该把所有的注册都取消掉。
1.2. 集合中的对象没有清理,造成的内存泄露

通常,我们会把一些对象的引用加入到集合中,当我们不需要该对象的时候,并没有及时的把引用从集合中清理掉。如果集合是Static的话,问题会很严重。


2.资源对象没有关闭,造成的内存泄漏

2.1.资源性的对象,都会用到一些缓冲,自不是用的时候,应该及时关闭,让系统能够及时的回收。例如:Cursor,File文件等。


3.不良代码

3.1. 在构造Adapter的时候没有私用convertView进行缓存。


3.2. Bitmap没有调用recycle()


3.3. 使用static定义成员变量的时候要注意。


4. 避免内存泄漏应注意以下几点

4.1. 不要对一个Activity Context保持长生命周期的引用(一个对Activity的引用应该与Activity自身的生命周期相同)

4.2. 尝试使用应用上下文(context-application)代替活动上下文(context-activity)

4.3. 如果你不能控制它们的生命周期,在活动(Activity)中避免使用不是静态的内部类,使用静态类并且使用弱引用到活动(Activity)的内部。对于这个问题的解决方法是使用静态的内部类与一个弱引用(WeakReference)的外部类。就像ViewRoot和它的W内部类那么实现的。




0 0