Android性能优化之内存泄漏

655 阅读4分钟

内存泄漏:内存单元使用完成后未释放,未回收。 理解强弱引用和gc垃圾回收机制后,会更好的理解内存泄漏问题。

在目前的Android项目中,内存泄漏是无法避免的,在编写代码时要是否产生了内存泄漏。内存泄露中要注意对象、变量等的回收时刻。 在内存泄露中,虽然存在gc回收机制,还是要搞明白,你声明的东西是何时创建的,何时回收的。简单来说,就是要知晓生命周期,了解越多这样的知识,对你的代码理解力就会有越多的提升。

一.static引发的内存泄漏:

在单例模式下,我们通常都会使用static修饰我们的对象,所以这里就要讲一下static所修饰的内容的生命周期了。

static:强调一下static修饰的内容通常是不会被gc系统回收的,所以该内容就会一直存在在系统中,那么,static总是会有销毁的时候吧: Lifetime of a static variable: A static variable comes into existence when a class is loaded by the JVM and dies when the class is unloaded,if you create an android application and initialize a static variable, it will remain in the JVM until one of the following happens:

  1. the class is unloaded
  2. the JVM shuts down
  3. the process dies 1.类被卸载的时刻。 2.JVM虚拟机关机的时刻。 3.进程被kill的时刻。 那么也就说static所修饰的内容和程序的生命周期是相关的。

接下来要说的东西就很好理解了:

1.单例模式的内存泄漏

一些单例模式中初始化时会传入context;当你传入Activity/Fragment的contenxt时;在该Activity/Fragment关闭,要被回收的时候,单例类还是会持有对Activity/Fragment的context引用,那么该Activity/Fragment就不会被回收,这样就造成了内存的泄漏。所以最好的解决办法是 传入Application的context即可,Application就是程序,他的context就是程序的context,所以与static的生命周期相同。例:getApplicationContext()。

2.非静态内部类创建静态实例造成的内存泄漏

内部类的最好优势就是默认会持有外部类的引用,而当你用这个非静态内部类创建了一个静态实例,那么麻烦来了,因为这个类并非静态类,所以这个类是可以被回收的,但是静态实例一值保持着对该非静态类的引用,造成了非静态内部类不能被回收,因为非静态内部类是不能脱离所属类而单独存活的,那么也就导致了外部类不能被回收,内存泄漏就产生了。解决办法当然是加上static,将非静态内部类变成静态内部类,静态内部类不依赖外部类,他们拥有不同的生命周期。

1).单例模式的静态内部类,这种写法的单例模式是最推荐使用的单例模式(详细可查看《Android源码设计模式解析与实战》)。
public class AppContext {

    public static AppContext getInstance() {
        return SingletonHolder.instance;
    }
    /**
     * 静态内部类的单例模式
     */
    private static class SingletonHolder{
        private static final AppContext instance = new AppContext();
    }
}
2).线程中的的内存泄漏

也可以归到内部类的静态使用。 线程的方式有Handler、AsyncTask、Thread等方式。 其中所有的线程方式在Activity中都是内部类的方式存在的,所以一般为了避免内存泄漏,都将这些线程实行静态内部类的方法。在Activity被销毁的时候,将线程关闭,清空线程中的任务。

所以一定要慎用static,在使用时要考虑到是否产生了内存泄漏。

二、资源未关闭产生的内存泄漏

这个就简单了,在使用BraodcastReceiver,ContentObserver,File,Cursor,Stream,Bitmap等后,要记得对资源进行手动回收,就避免了内存泄露。

这里对内存泄露进行了简单的分析,推荐好的博客: Android内存泄露——全解析和处理办法 Android开发中常见的5大内存泄漏问题及解决办法

有不对的地方欢迎大家指出来! 谢谢!!!