前几天,客户反馈应用有自动退出的现象。确认清楚后,是crash闪退,顿时有点慌啊。
因为终端是内网环境,于是联系客户把终端的日志用U盘拷贝出来,发给我。
通过日志排查,发现是OOM导致的crash,应用消耗了512M的内存,我去,怎么这么高。
这时感觉有2个问题(优先级排序):
1、可能是出现内存泄露的问题。
2、检查应用为什么占用这么高内存。(后续分析后补充)
首先要查泄露问题,想到了工具Profiler和LeakCanary。
先打开Profiler,点击MEMORY->然后点击,
然后回出现这个界面,可以直接看到有显示Leaks,点击可以看到泄露相关的Class。再选中class,打开右下角的框,References就是所有引用MainActivity的列表。
勾选Show nearest GC root only. 显示如下,现在已经比较明显了,就是因为这个引用导致没有释放。
然后结合代码,发现remoteSurfaceView里面有个成员eglRenderer,
然后EglRenderer中有个renderThreadHandler是负责更新view的,有依赖remoteSurfaceView的context。而Handler是系统层级的,不主动释放会一直持有MainActivity的引用。
于是需要调用SurfaceViewRenderer.release()以及eglRenderer.release();
这个加好以后实际还有mTarget也没有释放,mTarget是被native持有的。切断中间的联系后,再dump java heap就没有泄露了。
currVideoSink?.setTarget(null)
currVideoSink = null
期间也有接入leakcanary,发生泄露的时候都能显示出泄露信息。而后改完后没有发生泄露。
参考文档:
https://blog.csdn.net/liuhuiteng/article/details/106755587