内存泄露的检测和修复一直是每个APP的重点和难点,也有很多文章讲述了如何检测和修复。本篇文章
结合最近开发的项目遇到的实例,讲述下Android Binder导致的内存泄露的一个案例。
参与的项目在最近的版本接入了一个开源的内存检测工具LeakCanary,在提交给QA测试验证后。
瞬间检测出来N多的内存泄露,XXXActivity泄露,XXXActivity泄露…坑爹的是,这种泄露还不是必现的。好在堆栈都基本一样,随便拉一个出来分享吧
* com.ui.theme.ThemeListActivity has leaked:
* GC ROOT com.business.netscene.NetSceneBase1.this1.this0 (anonymous class extends com.data.network.framework.INetworkCallbackStub)∗referencescom.common.util.image.SceneBitmapDownload.info∗referencescom.common.util.image.BitmapDownloadInfo.imageLoadInterface∗referencescom.ui.common.RoundedImageViewStub)∗referencescom.common.util.image.SceneBitmapDownload.info∗referencescom.common.util.image.BitmapDownloadInfo.imageLoadInterface∗referencescom.ui.common.RoundedImageView4.this$0 (anonymous class implements com.common.util.image.ImageLoadInterface)
* references com.ui.common.RoundedImageView.mContext
* leaks com..ui.theme.ThemeListActivity instance
通过堆栈信息可以清楚的看到Activity到GCRoot的完整引用链,最终泄露是由于继承INetworkCallbackStub的匿名类没有被释放。通过函数名就可以知道INetworkCallbackStub的匿名类没有被释放。通过函数名就可以知道INetworkCallbackStub是Android自动生成的用于跨进程通信的框架,到对应的NetSceneBase查看对应的代码: