您的位置:首页 > 移动开发 > Android开发

Android 内存泄露

2016-02-20 08:35 288 查看
所谓内存泄露,即是当一段程序结束,需要释放资源时,而程序内部的某些对象,

又被其它更长生命周期(即还活着的)对象所引用,造成当前类不能及时释放,

造成内存空间浪费,越来越大。

在Android中,如果内存泄露的情况比较严重,则可能最后会引起OutOfMemory Exception

Android Context 分Activity的和Application的

Context 在创建广播、服务、View等地方都会用到

如一个Activity关闭,退出任务栈时,系统想要回收资源;

而某些操作导致某些类,仍持有Activity(或者说Context)的引用,而造成内存泄露

处理内存泄露

> Activity Context 和 ApplicationContext

 Activity的context较ApplicationContext 较为短暂。一些DB操作,一些工具单例类,可能需要传入Context。
这时,就不能图方便,传入this、MainActivity.this、getContext() 等仅表示Activity的Context;而是要传入ApplicationContext。

> Handler 引起的

在开发中,我们经常利用Handler,post一些message,或post一些(延迟)任务

那么当Activity退出时,Handler可能还在处理消息或任务

在Activity的onDestroy()中,可以调用

handler.removeCallbacksAndMessages(null); //如果设成null,则所有message和runnable都将remove

> getSystemService(String name)

某些定制系统,可能修改了底层源码,导致无法及时释放系统服务所引用的Context对象,
那么在获取系统应用时,改为:getApplicationContext().getSystemService(String name)

> 内部类

没有static修饰的内部类,即为成员内部类;有的即为静态内部类
成员内部类,会持有外部类的引用;静态内部类,不持有外部类的引用
在Activity、Fragment、View等有着的Context类中,如果需要创建内部类,最好都使用静态内部类
而我们在内部类中,一般都会引用外部类的某些方法或对象,
那么可以将外部类,使用一个软引用对象来引用
private static class S {

WeakReference<MainActivity> reference;
S(Context context) {
reference = new WeakReference<MainActivity>((MainActivity) context);
MainActivity activity = reference.get();
if (activity != null) {
//do something
}
}
}

> 动态的广播注册与反注册

动态广播的生命周期,应该随着当前Activity或其它你认为合适的对象生命周期一致
有了registerReceiver();一定不要忘了在适当的时候unregisterReceiver()

> Observer

Android中有ContentObserver
它的注册与反注册:
getContentResolver().registerContentObserver();

getContentResolver().unregisterContentObserver();

Java中的Observer
Observable的addObserver()、deleteObserver();

> Thread

要注意线程的及时退出

通常可以给线程一个标识变量

如 while (flag) {…}

> AsyncTask

适用于短时间的线程操作,如果需要比较耗时的线程操作,请用java.util.concurrent包下的

(比如Executor, ThreadPoolExecutor 和 FutureTask.)

AsyncTask的任务要适时取消掉。调用它的 cancel(true); //true表示是可以中断任务,false会先等待任务完成,再取消

在AsyncTask内部,可以加上if (!isCanceld()) {…} //只要调用了cancel(),则其内部的一个关于canceled的即为true

> ThreadPoolExecutor

要适时终止任务。它有shutdown()和shutdownNow(),及一个判断shutdown状态的 isShutdown()

shutdown() : 线程池的状态变为SHUTDOWN,不能再向它提交新的任务,但要等待池中的任务完成后,才能退出

shutdownNow():线程池的状态变为STOP,试图停止池中正在运行的所有任务,并不再执行池中等待的任务,

并返回等待执行的任务列表。它试图终止线程的方法是通过调用Thread.interrupt()方法来实现的,

但是大家知道,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用, 

interrupt()方法是无法中断当前的线程的。所以,ShutdownNow()并不代表线程池就一定立即就能退出,

它可能必须要等待所有正在执行的任务都执行完成了才能退出。 简单的处理就是在程序适当的地方加上

sleep 、wait、Condition、定时锁等

> Timer、TimerTask

不要忘了它俩的cancel()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: