鴿了好久, 如今補上緩存
上篇提到, 作好方法堆棧的收集後, 項目工程運行不到兩分鐘, 出先卡頓, 直至完全卡死.markdown
經過Android Studio Profile調查得知, 正是我統計耗時的MethodNode堆棧撐爆了內存.app
爲了監控方法耗時, 可是居然搞出了內存問題, 有些搞頭..spa
由於每一個方法都被插樁, 因此每一個方法的先後調用關係都作成MethodNode被存到了堆棧中,設計
因此隨着使用時間的增加, 全部方法關係都存進了堆棧中, 不被清理, 就撐爆了內存.code
這個問題其實是個OOM問題. OOM從技術角度看, 是由於改釋放的內存不被釋放.orm
可是要解決OOM問題, 卻須要從具體業務入手, 由於只有經過業務關係梳理, 才知道那些內存應該釋放.對象
針對此次的問題, 就是要減小方法關係的存儲.內存
由於MethodNode中保存了父節點和子節點信息. 因此當獲得一個新MethodNode時,開發
獲取它的父節點信息, 再從現有的堆棧中, 找到對應的父節點,
查看該父節點中的全部子節點是否已經包含那個新MethodNode的信息.
若是包含, 說明重複, 則丟棄這個新MethodNode. 若是不包含, 就把新MethodNode加入堆棧裏父節點的子節點列表裏,
若是沒有找到父節點, 則這個新MethodNode直接當作root級別父節點, 存入堆棧
聊這個, 我可就不困了.
特別爲這個設計裏一個存取交換池.
簡單的說, 設計了兩個緩存池, 某個時間段內, 一個池只取, 另外一個池只存.
當"只取"的池子空了, 就切換成"只存"狀態. 同時, 以前"只存"的池子同步切換爲"只取"
這樣兩個池子, 交替使用
若是兩個坑都沒有磚, 我就去找磚廠要磚. 回收的磚一樣按照輪換扔到當前應該回收轉的坑裏.
至關於作到存取隔離, 也就沒有了存取衝突. 同時有複用機制. 內存的數量不會激增.
過程大體以下:
按照設計, 開發完畢實測.
緩存池初期不斷增大, 2w個以後逐漸穩定.再也不增加.
知足了整個app的循環複用. 內存問題解決.