延续Android Memory Leak及衍伸问题01
在第一篇中我们讨论到的方式是手动释放记忆体
在这边我们试着用另一种方式处理
首先要先大概介绍一下本次要使用的物件及相关的家人
StrongReference(强引用)
SoftReference(软引用)
WeakReference(弱引用)
PhantomReference(虚引用)
StrongReference(强引用)
基本上我们平常宣告物件的方式就是一种强引用(new Object()这类的写法),既然如此那为何还硬要定义一个强引用的物件
我自己猜想,或许想用的某些物件会因为受到生命週期的影响而被回收,所以把他刻意放到强引用中或许就能降低它被回收的风险(纯属猜测)
SoftReference(软引用)
被放到软引用内的物件,会在记忆体不足的时候被回收,所以大概满适合用来放一些,会很常被使用但没有也不会太严重的资料。举个例子,例如APP背景图片,可能到每个页面都会用到,但是不显示说实在不会太影响APP功能使用
WeakReference(弱引用)
当Garbage Collection启动时,不论记忆体是否充足,都有可能回收到弱引用存取的参数(被回收机率比软引用大),至于这个"可能回收"的状况是怎么发生的,我猜想规则可能也是用LRU的方式吧
PhantomReference(虚引用)
这名字听起来就真的够虚了,实际使用状况也确实很虚,自己实测了一下发现不管什么状况都是null,马上看一下Google官方Document,看完后觉得一阵尴尬,所以我说这东西到底要用在哪还真的没概念
到这边就介绍完本次会使用来处理Memory Leak的物件了
实测
马上来测试有没有用,跟上一篇用一样的写法,这是我们把Context放到WeakReference中,同样离开APP
本次测试leakcanary就没有侦测到Memory Leak的状况(使用SoftReference也可以达到一样的效果)
可以看到下图撰写方式有点奇怪,主要是想测试手动呼叫GC是否能把WeakReference回收掉(很明显的是不行XD)
其实还有做一个更极端的测试,在两个Log中间插入多次的Bitmap decode动作把记忆体逼到极限,再试试看GC之后WeakReference是否还活着。这边使用的test2图片实际档案约3MB,在手机上测试有时候再多读取一张就会Crash,但呼叫GC后仍然没有把WeakReference回收
结论
使用这种Reference类的方法,确实可以避免掉Memory Leak问题,但实际资料被回收的时机就完全是交给系统了
各位大大如果有更好的测试方式欢迎分享讨论