Android 内存泄露
2016-02-20 08:35
288 查看
所谓内存泄露,即是当一段程序结束,需要释放资源时,而程序内部的某些对象,
又被其它更长生命周期(即还活着的)对象所引用,造成当前类不能及时释放,
造成内存空间浪费,越来越大。
在Android中,如果内存泄露的情况比较严重,则可能最后会引起OutOfMemory Exception
Android Context 分Activity的和Application的
Context 在创建广播、服务、View等地方都会用到
如一个Activity关闭,退出任务栈时,系统想要回收资源;
而某些操作导致某些类,仍持有Activity(或者说Context)的引用,而造成内存泄露
这时,就不能图方便,传入this、MainActivity.this、getContext() 等仅表示Activity的Context;而是要传入ApplicationContext。
那么当Activity退出时,Handler可能还在处理消息或任务
在Activity的onDestroy()中,可以调用
handler.removeCallbacksAndMessages(null); //如果设成null,则所有message和runnable都将remove
那么在获取系统应用时,改为:getApplicationContext().getSystemService(String name)
成员内部类,会持有外部类的引用;静态内部类,不持有外部类的引用
在Activity、Fragment、View等有着的Context类中,如果需要创建内部类,最好都使用静态内部类
而我们在内部类中,一般都会引用外部类的某些方法或对象,
那么可以将外部类,使用一个软引用对象来引用
有了registerReceiver();一定不要忘了在适当的时候unregisterReceiver()
它的注册与反注册:
getContentResolver().registerContentObserver();
getContentResolver().unregisterContentObserver();
Java中的Observer
Observable的addObserver()、deleteObserver();
通常可以给线程一个标识变量
如 while (flag) {…}
(比如Executor, ThreadPoolExecutor 和 FutureTask.)
AsyncTask的任务要适时取消掉。调用它的 cancel(true); //true表示是可以中断任务,false会先等待任务完成,再取消
在AsyncTask内部,可以加上if (!isCanceld()) {…} //只要调用了cancel(),则其内部的一个关于canceled的即为true
shutdown() : 线程池的状态变为SHUTDOWN,不能再向它提交新的任务,但要等待池中的任务完成后,才能退出
shutdownNow():线程池的状态变为STOP,试图停止池中正在运行的所有任务,并不再执行池中等待的任务,
并返回等待执行的任务列表。它试图终止线程的方法是通过调用Thread.interrupt()方法来实现的,
但是大家知道,这种方法的作用有限,如果线程中没有sleep 、wait、Condition、定时锁等应用,
interrupt()方法是无法中断当前的线程的。所以,ShutdownNow()并不代表线程池就一定立即就能退出,
它可能必须要等待所有正在执行的任务都执行完成了才能退出。 简单的处理就是在程序适当的地方加上
sleep 、wait、Condition、定时锁等
又被其它更长生命周期(即还活着的)对象所引用,造成当前类不能及时释放,
造成内存空间浪费,越来越大。
在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()相关文章推荐
- Android线程二、异步加载-新闻列表
- Android连接不上ss原因
- Android之史上最全最简单最有用的第三方开源库收集整理
- android中使用Notification打开详情界面activity,点击返回键和按钮返回主界面
- Android - 打造3D自定义view
- 针对Android的重新认识OOP(下)
- android 成长日记 3.关于Activity的用户体验提升办法和使用技巧说明
- android自定义控件实现左右划出菜单并添加点击事件
- Android Widget小组件开发(一)——Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的!
- Android Widget小组件开发(一)——Android实现时钟Widget组件的步骤开发,这些知识也是必不可少的!
- android自定义控件波纹ripple效果
- Android Studio 学习笔记01
- 解决maven管理Android项目时pom报错Unknown packaging: apk
- Android 的性能工具用法 III-Traceview
- Android 异常 Didn't find class .... on path: DexPathList[[z
- 模仿QQ快速显示图片效果
- [Android Pro] Android 官方推荐 : DialogFragment 创建对话框
- ViewPager与PagerAdapter深度解析
- Android Handler内存泄露分析
- Android Studio的使用