根据及时清理数据这一方法论设计出来的优化方案往往都是应用层的优化方案,这些方案一般都比较容易落地而且有较好的效果。大多数情况下,我们只需要在业务结束时和内存不足时进行数据清理。
1.业务结束时
业务结束时,有些数据需要手动进行清理,比如全局的缓存和资源。有些数据会自动清理,比如Activity及其成员变量。对于需要手动清理的数据,我们要避免清理后因为还有业务使用该数据导致空异常。因为清理这类数据很容易发生异常,所以一定要谨慎,或者尽量将需要手动清理的全局数据放入Activity中,将其转为Activity成员数据。
对于Activity来说,当它被执行销毁操作后,只要这个Activity不被其他地方的某个对象长期持有,那么当虚拟机执行GC时,这个Activity及其成员变量就会被释放掉。在现实中,对于这类业务结束时自动清理的数据,优化工作更多集中在内存泄漏的排查和治理上。但是我们依然可以在排查和治理之外增加一些防御型的优化策略,比如我们可以把持有Activity的上下文(context)代码改成持有Application的上下文代码,如果不能持有Application的上下文,也应该以弱引用持有该Activity的上下文。
2.内存不足时
在内存不足时,我们也需要主动清除非必要的对象和数据,比如在Java堆内存不足时,对应用中的缓存进行清理。那如何才能知道Java堆内存不足呢?这就需要增加一个检测机制了。我们可以开启一个独立的子线程,然后按照一定的频率进行检测以获取Java堆信息,可以采用通过AMS获取memoryInfo的方式,也可以通过Runtime.getRuntime()接口来获取。一般来说,用Runtime.getRuntime()是合适的,因为这种方式对性能的影响最小,并且我们只需要知道Java堆的最大内存和已经使用的内存即可。
当得到最大可使用内存和已经使用的Java堆内存后,我们便能判定内存的使用是否超过了设定的阈值,如果超过了就通过回调通知各个业务、缓存、单例对象等进行缓存的清理工作。