Android内存泄漏

来源:互联网 发布:做微信淘客用什么软件 编辑:程序博客网 时间:2024/06/06 12:35

android内存泄漏

一句话总结,内存泄漏就是一些资源没有手动回收,而他们又不满足gc回收条件,一直存在内存中,这样的对象多了占用大量内存,导致app发生oom

Android常见内存泄漏

1.非静态匿名内部类造成内存泄漏

这是最常见的内存泄漏,一句话就是:如果Activity结束了,而Thread或者handler等耗时操作还在跑,同样会导致Activity内存泄漏,这是因为new Thread和handler作为非静态内部类对象都会隐式持有一个外部类对象的引用,我们所创建的线程就是Activity中的一个内部类,持有Activity对象的引用,所以当Activity 结束了,而子线程还在跑就会导致Activity内存泄漏。

1 handler如下代码就会发生内存泄漏,因为activity,handler继续在运行。。

public class MainActivity extends AppCompatActivity {    private final Handler myHandler = new Handler(){        @Override        public void handleMessage(Message msg) {            //doSomething        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        myHandler.postDelayed(new Runnable() {            @Override            public void run() {                //doSomething            }        },2000000);    }}

解决办法:
在ondestroy中把handler消息队列清空
声明handler为static类,这样内部类就不再持有外部类的引用了,就不会阻塞Activity的释放,如果内部类实在需要用到外部类的对象,可在其内部声明一个弱引用引用外部类。

2.Thread造成内存泄漏

在子线程中执行网络请求,数据库查询这些耗时操作。当我们需要开启的子线程比较少的时候,直接new Thread(Runnable)就可以了。如果你经常这样做的话就说明你没有注意到有可能会产生内存泄漏的问题。
`public class MainActivity extends AppCompatActivity {

@Overrideprotected void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    newThread();}private void newThread() {    new Thread(new Runnable() {        @Override        public void run() {            while (true){                SystemClock.sleep(200000);            }        }    }).start();}

}`

解决办法:
同样把Thread定义为静态的内部类,这样就不会持有外部类的引用。

2.非静态内部类存在静态实例 (单例模式)

非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。

3.资源对象未关闭

资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,,我们在不使用的时候,应该及时关闭它们, 以便它们的缓冲及时回收内存。

4.一些不良代码习惯

有些代码并不造成内存泄露,但是他们的资源没有得到重用,频繁的申请内存和销毁内存,引起内存泄漏
解决方案 如果需要频繁的申请内存对象和和释放对象,可以考虑使用对象池来增加对象的复用。 例如ListView便是采用这种思想,通过复用converview来避免频繁的GC

1 0