记一次内存泄漏

122 阅读2分钟

使用profiler,可以看到mContext被 NewsSmallDetailPlayer引用,(这个mContext被传入的是activity)然后Player被BaseVideoPlayer引用,直到系统的代码层

image.png

此时查看BaseVideoPlayer的onDestroy,release操作,都已经切断回收了所有的资源包括context。这是一个列表的播放器,每次播放时都会去预加载上个和下一个视频,释放操作也都看着没有问题,播放时和VideoPlayer detachWinodow时就去回收该VideoPlayer。

打开/Android/Sdk/platform-tools/hprof-conv进行转换,在mat上看看有没有什么线索

hprof-conv '/home/meizu/下载/com.flyme.videoclips (1).hprof' /home/meizu/桌面/1.hprof点击 OQL 和 红色感叹号 使用命令

select * from instanceof android.app.Activity,可以看到Activity泄露相关的类

image.png 右键Merge Shortest Path to GC Root - > exclude all phantom/soft/weak etc. reference 可以看到剩下的强引用

image.png

最后引用到了Application,后来想想应该是mediaPlayer会引用到application,所以使用mediaplayer等等要做好回收操作。

既然Gc Root 找到了,说明不是下游的问题,是上游的问题,BaseVideoPlayer为什么还会存在,mContext为什么还会被引用。

最相关的类就是这个BaseVideoPlayer:

  1. activity与BaseVideoPlayer没有被切断:查看BaseVideoPlayer代码,被引用的activity,没有进行注册广播等等的操作,也在destroy中被及时回收置空被释放掉了
  2. BaseVideoPlayer与Application没有被切断:但是查看代码,BaseVideoPlayer也在destroy中会被release掉并置空

没有其他异常,那八成是BaseVideoPlayer没有被调用destroy方法

经过排查,发现该页面会存在广告,广告展示时没有去及时释放预加载的VideoPlayer,由于没有展示在屏幕上VideoPlayer的detachFromWindow方法中的release操作也没有得到执行,导致内存泄露。

另外在网上看到MAT的其他使用

image.png

点击Histogram -> 文件夹图标 -> Group by Package可以快速查找到某个类是否还被持有,是否被释放

image.png

比如这里被释放后,还有5个NmdPlayerManager实例,就是有问题的

点击Leak Suspects,说是会给一些实用的建议,反正这次是没发现,也没有其他提示

0

0