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 細枝末節的 變化太*了。。。大家可以自行嘗試,有結論 求告知~

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