美文网首页
内存泄漏分析

内存泄漏分析

作者: 小马要加油 | 来源:发表于2019-07-27 17:21 被阅读0次

问题

昨天一老哥非说我负责的模块内存泄漏,导致anr了。


image.png

这个view看起来是有点恐怖呀,可是这个模块虽说是我负责的,but不是我写的呀。

过程

不过没关系,不是有个很强大的LeakCanary吗,上次就是借助这个工具发现了三处泄漏,而且这个导入非常简单,在build.gradle导入依赖就好了。

我就按照教程

 dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
 }

。。。
sync一下
。。。


竟然成功了,本来想记录一次失败的操作(前面添加官网最新的失败了好几次),然后秀一下技术,表示我不用这个插件也能找到哪里泄漏的。进入成功了,不用白不用,那这个就改成 《手把手教你使用leakcanary找到内存泄漏》吧。

接下来
在这个应用的Application添加上
LeakCanary.install(this);
这句。

接下来
。。。
安装
。。。


image.png

接下来
。。。
在你的应用随便点点,多操作几次
。。。

操作一通后,没有发现有提醒内存泄漏
但是dumpsys activity activities之后发现了一些问题
这个应用所处的任务栈有有很多activity是一样的,难道是因为这个导致没有释放掉这个些view?
用mat抓出来看下。
具体操作可以看下我的这篇笔记。
文档:内存泄漏分析工具.note
链接:http://note.youdao.com/noteshare?id=05cb734880cb162ded31f429d9f215ae&sub=57AB6263DEC3423DBBB7CA4777408B13

image.png

dump出来确实看到有很多settings 实例。
在研究中,找到原因再更新

-------------------------------------两个小时后------------------------------------------------------------------------
hhhhhh我又回来了。

原因是这样:
我们的应用有两个入口进入,一个是launcher进入,一个是从systemUI进入。Launcher进入就是原生的操作,startActivity

    String packageName = componentName.getPackageName();
            String className = componentName.getClassName();
            Intent intent = new Intent(Intent.ACTION_DELETE, Uri.fromParts(
                    "package", packageName, className));
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
            startActivity(intent);
            return true;

从systemUI进入的就是我们自己写的。

 Intent intent = new Intent(action);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(CommonActionDefine.KEY_ACTION_FROM,from);
            context.startActivity(intent);

启动都是FLAG_ACTIVITY_NEW_TASK,跟踪源码会发现。
如果从Launcher进入,那么任务栈里进入一个activity,然后在下拉通知栏从SystemUI进入,Activity作为SingleTask,那么系统就会去找当前是否有这个栈,对比栈

07-27 17:18:27.404 D/ActivityManager(  607): Looking for task of ActivityRecord{2c763290 u0 com.XXX.setting/.SettingActivity t-1}
07-27 17:18:27.404 D/ActivityManager(  607): Looking for task of ActivityRecord{2c763290 u0 com.XXX.setting/.SettingActivity t-1} in ActivityStack{1c759c1e stackId=1, 10 tasks}
07-27 17:18:27.404 D/ActivityManager(  607): Comparing existing cls=com.XXX.setting/.SettingActivity/aff=com.XXX.setting to new cls=com.XXX.setting/.SettingActivity/aff=com.XXX.setting
07-27 17:18:27.404 D/ActivityManager(  607): Found matching affinity!
07-27 17:18:27.404 D/ActivityManager(  607): Bring to front target: ActivityStack{1c759c1e stackId=1, 10 tasks} from ActivityRecord{17578b5c u0 com.XXX.setting/.status.StatusSettingActivity t75}
07-27 17:18:27.404 I/am_home_stack_moved(  607): [0,0,1,1,intentActivityFound]

找到之后直接将这个Activity移到前台。
看样子我们的应该是这样,不需要重新启动,直接将之前的应用给移到前台即可。
但是dumpsys activity activities之后发现,这个任务栈有两个一样的hist,除了一个是Resume状态一个是Stop状态之前,调用它启动的应用也不一样之外,其他一样,那为什么他不找之前那个应用呢。
(这部分源码在ActivityStack里,这里偷个懒就不拿出来了)
结果就是ActivityManager除了找亲和力一致之外,还要对比Intent是否一致,一致的话才是找对了,不能你叫彭于晏,你就是彭于晏吧。intent对比的内容是这样

  public boolean filterEquals(Intent other) {
        if (other == null) {
            return false;
        }
        if (!Objects.equals(this.mAction, other.mAction)) return false;
        if (!Objects.equals(this.mData, other.mData)) return false;
        if (!Objects.equals(this.mType, other.mType)) return false;
        if (!Objects.equals(this.mPackage, other.mPackage)) return false;
        if (!Objects.equals(this.mComponent, other.mComponent)) return false;
        if (!Objects.equals(this.mCategories, other.mCategories)) return false;

        return true;
    }

只要这里有一个不一样,就不是彭于晏哈哈。
所以我这里又启动了一个Activity,那么重复这样的操作,名义上一个Activity后台上存在N多个,所以View才多,所以周末这样的好日子我在这里被逼着改内存泄漏问题。

解决

那么怎么解决这个问题呢?把启动这个应用的Intent要求的都整一样?不行,我这边有个需求就是需要区分两个入口。就是settings要知道是launcher启动的还是systemUI启动的,而且这边不止这一个activity。
如果每次从systemUI启动之前能把这个栈的Hist给清一清就好了,
清?
有啊
FLAG_ACTIVITY_CLEAR_TASK
这个不就好了!!!
加上这个之后,每次启动systemUI的settings时,都会把栈清理干净,哈哈哈。没毛病
改完dump一下


ok,下班!!!!!!!!!!!!

相关文章

网友评论

      本文标题:内存泄漏分析

      本文链接:https://www.haomeiwen.com/subject/dwrerctx.html