egret chrome profile 内存未清理处理

白鹭打包微信小游戏,内存占用随时间增长,wxtool上还是 wing内置的 类chrome调试器,用法都差不多,但是初次用的话 ,烦乱的 object 们 还是 很麻烦的

 

主要用到的是profiles的 record allocation timeline,字面意思,记录 内存分配 时间线。

start 就可以 开始记录 游戏 内存 分配情况,点 红点 关闭就 生成分析文件

这里主要 介绍一下 调试思路,方法~具体 界面上 的各个名词 ,可以百度~ 还是有的,基本就是字面意思

1. 第一点就是 因为 js 是GC 管理 内存 回收,所以 不能 去看实时的 或者很短的记录 就 判断 是否  是泄露,未回收的内存。

        要长一点时间,规律明显的 才行。标点1 的 时间线上,灰条就是 分配的 但已回收的内存,蓝条就是 没回收的内存,

        所以 主要追查 蓝条,同时注意,调试中,把游戏窗口 鼠标聚焦,让其活跃,否则 wing默认 stop 不运行的。。。

2.主要 的 追查就是 distance 属性,界面 上 除了 时间线,就是 上面的 constructor 和 持有者实例了,就是说,

        上面是被分配的实例的构造器(类名,所以如果有思路 知道大概是哪个类 泄露了,就 可以 根据类名 筛选,不过像我,

        不知道哪里泄露的,只能根据距离去判断了 )。distance的意思 就是 距离,当前实例 距离 实际被泄露 的 实例的调用距离,

        就是 套了几层函数调用,比如

a () =>{ 
    b()=>{ 
        return c()=>{ 
            while(true){}
        }
    }; 
}
let s = a(); 

这样 c函数 在运行时 距离 window or document 就是 3的距离,实际在 运行的 是 c函数,但是 a函数和b函数 都没有被 释放掉,他们距离分别是 3/2.

c函数 就是距离1 ,实际 发生被占用的 内存实例。

所以 关键是找到 distance = 1,

先在 构造器列表 找到比较小的,然后 去点击 类名下面的 实例,然后去 5 里面去找 距离为 1 的实例。

注意 标号3.那里,主要有两种,一是 (array)/(systeam)/Array/(编译码) 等,这些 其实 是 实际的 内存占用 数据,看他们太麻烦,可以 去看第二类,就是 有 实际 自定义的 类名的 类,比如 XXXgameMainClass 比如 图中的 Image ,但是 实际上不用看这种,还是 就看 具体的 逻辑类即可,白鹭或者 js自带的 类先不用看,比如图中 @1766049 实例再看 下面,这个实例 被存储在Array @1080741 中的 第6个,然后 同理向上,1080741 在 720439 中,直到,到了 “距离” 为 1 的 构造器,这里只是举例,实际 逻辑类 的构造器就简单明了了,基本就能定位 是 实例谁 被什么函数 调用了,层层向 里 最后占有了,

不过基本上不用 看太多,就知道 是哪个类的某 实例 被 泄露了,然后 看下面 第一个 被谁占有了,基本就知道 是哪里 持有了 ,然后看 是 不是 listener 没有释放,还是 引用类型变量 忘了 赋 null,不推荐 赋值 null,因为 我不知道 为什么要主动赋值null。找不到就 再看整个链上,哪里有可能 是 被占用了,忘了释放,

我查到的一个 就是 a类 继承自 b 类,super 的构造器中,添加了给this 几个listener,但是 子类a 销毁时,类似于没有调用 super.destroy 也就是没有 销毁 父类给他注册的 listener 所以 导致 a实例 一直占有 内存。

另一个就是 一个 this.a = [1,2,3]; this.a = [2,3,4]; 这时候 [1,2,3]就被泄露了,具体为啥,不清楚,我直接 let cc = this.a;cc = null;this.a =[2,3,4]; 就好了,我也懒得追究了,js 细枝末节的 变化太*了。。。大家可以自行尝试,有结论 求告知~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章