所谓内存泄露,即是当一段程序结束,需要释放资源时,而程序内部的某些对象,
又被其它更长生命周期(即还活着的)对象所引用,造成当前类不能及时释放,
造成内存空间浪费,越来越大。
在Android中,如果内存泄露的情况比较严重,则可能最后会引起OutOfMemory Exception
AndroidContext 分Activity的和Application的
Context 在创建广播、服务、View等地方都会用到
如一个Activity关闭,退出任务栈时,系统想要回收资源;
而某些操作导致某些类,仍持有Activity(或者说Context)的引用,而造成内存泄露
处理内存泄露
> Handler 引起的
在开发中,我们经常利用Handler,post一些message,或post一些(延迟)任务
那么当Activity退出时,Handler可能还在处理消息或任务
在Activity的onDestroy()中,可以调用
handler.removeCallbacksAndMessages(null); //如果设成null,则所有message和runnable都将remove
>getSystemService(String name)
> 内部类
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
}
}
}
> 动态的广播注册与反注册
> Observer
getContentResolver().unregisterContentObserver();
> 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()