背景
笔者最近承接项目的内存优化工作,在预研的过程中发现一篇关于内存优化的文章 《优化安卓应用内存的神秘方法以及背后的原理,一般人我不告诉他》
里面介绍了一个方法
WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE);
但是应用层无法直接访问 WindowManagerGlobal,因此笔者采取反射来验证这个方案的可行性。
方案实现
private fun startTrimMemory() {try {val windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal")val getInstanceMethod = windowManagerGlobalClass.getDeclaredMethod("getInstance")val windowManagerGlobalInstance = getInstanceMethod.invoke(null)val startTrimMemoryMethod = windowManagerGlobalClass.getDeclaredMethod("trimMemory",Int::class.javaPrimitiveType)// TRIM_MEMORY_COMPLETE 对应的值为 80val trimMemoryCompleteValue = 80startTrimMemoryMethod.invoke(windowManagerGlobalInstance, trimMemoryCompleteValue)} catch (e: Throwable) {}}
项目中打开视频播放页面,播放视频,待内存稳定后,退出播放页面,观察内存变化:
播放页面,播放视频中
退出播放页面后
对比看出, Graphics 内存下降最为明显, Java 部分内存次之,其他部分变化不大。
如同原文作者所说 “应用开发者调用 startTrimMemory 会帮助 app 或者系统更多的释放内存,减少内存压力,但是调用的位置和时机要慎重,因为清除了缓存,在下一次绘制(vsync的下一个信号到来)的时候绘制效率不会很高。”
目前方案验证有效,但是在实际项目中还需要探索验证调用的场景和时机,后续笔者上线后更新效果。