衔接上篇:
新年事后献上关于Android内存泄漏的种种总结
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)git
在Android应用的开发中,为了防止内存溢出,在处理一些占用内存大并且声明周 期较长的对象时候,能够尽可能应用软引用和弱引用技术。github
软/弱引用能够和一个引用队列(ReferenceQueue)联合使用,若是软引用所引用 的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队 列中。利用这个队列能够得知被回收的软/弱引用的对象列表,从而为缓冲器清除已 失效的软/弱引用。 面试
假设咱们的应用会用到大量的默认图片,好比应用中有默认的头像,默认游戏图标 等等,这些图片不少地方会用到。若是每次都去读取图片,因为读取文件须要硬件 操做,速度较慢,会致使性能较低。因此咱们考虑将图片缓存起来,须要的时候直 接从内存中读取。可是,因为图片占用内存空间比较大,缓存不少图片须要不少的 内存,就可能比较容易发生OutOfMemory异常。这时,咱们能够考虑使用软/弱引 用技术来避免这个问题发生。数组
如下就是高速缓冲器的雏形: 首先定义一个HashMap,保存软引用对象。缓存
private Map <String, SoftReference<Bitmap>> imageCache = new Has hMap <String, SoftReference<Bitmap>> ();
再来定义一个方法,保存Bitmap的软引用到HashMap
。
使用软引用之后,在OutOfMemory异常发生以前,这些缓存的图片资源的内存空间 能够被释放掉的,从而避免内存达到上限,避免Crash发生。 若是只是想避免OutOfMemory异常的发生,则可使用软引用。架构
若是对于应用的性 能更在乎,想尽快回收一些占用内存比较大的对象,则可使用弱引用。 app
另外能够根据对象是否常用来判断选择软引用仍是弱引用。若是该对象可能会 常用的,就尽可能用软引用。若是该对象不被使用的可能性更大些,就能够用弱 引用ide
ok,继续回到主题。前面所说的,建立一个静态Handler内部类,而后对 Handler 持有的对象使用弱引用,这样在回收时也能够回收 Handler 持有的对象,可是这样 作虽然避免了 Activity 泄漏,不过 Looper
线程的消息队列中仍是可能会有待处理的 消息,因此咱们在 Activity 的 Destroy 时或者 Stop 时应该移除消息队列 MessageQueue
中的消息。 oop
下面几个方法均可以移除 Message:性能
public final void removeCallbacks(Runnable r); public final void removeCallbacks(Runnable r, Object token); public final void removeCallbacksAndMessages(Object token); public final void removeMessages(int what); public final void removeMessages(int what, Object object);
尽可能避免使用 static 成员变量
若是成员变量被声明为 static,那咱们都知道其生命周期将与整个app进程生命 周期同样。
这会致使一系列问题,若是你的app进程设计上是长驻内存的,那即便app切到 后台,这部份内存也不会被释放。按照如今手机app内存管理机制,占内存较 大的后台进程将优先回收,由于若是此app作过进程互保保活,那会形成app在 后台频繁重启。当手机安装了你参与开发的app之后一晚上时间手机被消耗空了 电量、流量,你的app不得不被用户卸载或者静默。 这里修复的方法是:
不要在类初始时初始化静态成员。能够考虑lazy初始化。 架构设计上要思考是否真 的有必要这样作,尽可能避免。若是架构须要这么设计,那么此对象的生命周期你有 责任管理起来。
override finalize()
二、finalize 方法只会被执行一次,即便对象被复活,若是已经执行过了 finalize 方法,再次被 GC 时也不会再执行了,缘由是:
含有 finalize
方法的 object 是在 new 的时候由虚拟机生成了一个 finalize reference
在来引用到该Object的,而在 finalize 方法执行的时候,该 object 所 对应的 finalize Reference
会被释放掉,即便在这个时候把该 object 复活(即用 强引用引用住该 object ),再第二次被 GC 的时候因为没有了 finalize reference
与之对应,因此 finalize 方法不会再执行。
三、含有Finalize方法的object须要至少通过两轮GC才有可能被释放。
BraodcastReceiver
,ContentObserver
,File,游标 Cursor, Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或者注销,否 则这些资源将不会被回收,形成内存泄漏。好比:
构造 Adapter 时,没有使用缓存的 convertView
,每次都在建立新的 converView
。这里推荐使用 ViewHolder
。
getApplicationContext
或者 getApplication
,以免 Activity 被外部长 生命周期的对象引用而泄露。Activity onStop
或者 onDestroy
的时候,取消掉该 Handler
对象的 Message
和 Runnable
.BraodcastReceiver
,ContentObserver
,File,游 标 Cursor,Stream,Bitmap等资源的使用,应该在Activity销毁时及时关闭或 者注销。 删减了一部分,见谅^_^
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MS
(VX:mm14525201314)