學習八、JavaScript的記憶體管理及垃圾回收(GC演算法)

想去阿里的Misoka發表於2020-10-01

一、記憶體管理

    1) 記憶體:由可讀寫單元組成,表示一片可操作空間

    2) 管理:人為的去操作一片空間的申請,使用和釋放

    3) 記憶體管理:開發者主動申請空間,使用空間,釋放空間

    4) 管理流程:申請————使用————釋放

 

二、垃圾回收與常見 GC 演算法

1、JavaScript中的垃圾回收

      1) JavaScript 中的記憶體管理是自動的

      2) 物件不再被引用時是垃圾

      3) 物件不能從根上訪問到時是垃圾

JavaScript的可達物件:我們可以訪問到的物件就是可達物件(引用、作用域鏈)

      ————可達的標準就是從根上觸發是否能夠被找到

JavaScript中的根可以理解為是全域性變數物件

 

2、GC的定義與作用

        1) GC就是垃圾回收機制的簡寫

        2) GC可以找到記憶體中的垃圾、並釋放和回收空間

            程式中不再需要使用的物件、程式中不能再訪問到的物件

        3) 演算法就是工作時查詢和回收所遵循的規則

        (引用計數、標記清除、標記整理、分代回收)

 

3、 引用計數演算法:

        核心思想:設定引用數,判斷當前引用數是否為0

        引用計數器

        引用關係改變時修改引用數字

        引用數字為0時立即回收

        優點  發現垃圾時立即回收,最大限度減少程式暫停

        缺點  無法回收迴圈引用的物件,資源消耗比較大

 

4、 標記清除演算法:

        核心思想:分標記和清除兩個階段完成

        遍歷所有物件找到並標記活動物件

        遍歷所有物件清除沒有標記的物件

        回收相應的空間

        優點  可以找到一些區域性作用域的垃圾,可以解決引用計數演算法中無法回收迴圈引用的問題

        缺點  不會立即回收垃圾物件,地址不連續、空間碎片化、浪費空間

 

5、 標記整理演算法:

        標記整理可以看作是標記清除的增強

        標記階段的操作和標記清除一致

        清除階段會先執行整理,移動物件位置

        優點  減少碎片化空間

        缺點  不會立即回收垃

 

三、V8 引擎的垃圾回收

    1) V8是一款主流的JavaScript執行引擎

    2) V8採用即時編譯

    3) V8記憶體設限(64位1.4G,32位800MB)

 

    1、V8垃圾回收策略

        1) 採用分代回收的思想

        2) 記憶體分為新生代、老生代

 

    2、V8中常見的GC演算法

        * 分代回收

        * 空間複製

        * 標記清除

        * 標記整理

        * 標記增量

 

    3、V8如何回收新生代物件

        1) V8記憶體空間一分為二

        2) 小空間用於儲存新生代物件(32M | 16M)

        3) 新生代制的是存活時間較短的物件

 

        新生代物件回收實現:

        1) 回收過程採用複製演算法+標記整理

        2) 新生代記憶體區分為二個等大空間,使用空間為From,空閒空間為To

        3) 活動物件儲存於From空間

        4) 標記整理後將活動物件拷貝至To

        5) From和To交換空間完成釋放

 

    回收細節說明

        1) 拷貝過程中可能出現晉升

        2) 晉升就是將新生代物件移動至老生代

        3) 一輪GC還存活的新生代需要晉升

        4) To空間的使用率超過25%

 

    4、V8如何回收老生代物件

        1) 老生代物件存放在右側老生代區域

        2) 大空間用於儲存老生代物件(1.4G | 700M)

        3) 老生代物件就是指存活時間較長的物件(全域性變數,閉包)

 

        老生代物件回收實現:

        1) 主要採用標記清除、標記整理、增量標記演算法

        2) 首先使用標記清除完成垃圾空間的回收

        3) 採用標記整理進行空間優化(當新生代晉升老生代時,老生代空間的碎片不足以存放時)

        4) 採用增量標記進行效率優化

 

    5、增量標記優化垃圾回收

        程式執行時交替執行垃圾回收處理,分層遍歷物件進行標記,最後完成清除。

 

四、Performance 工具

 

    1、GC的目的是為了實現記憶體空間的良心迴圈

    2、良心迴圈的基石是合理使用

    3、時刻關注才能確定是否合理

    4、Performance提供多種監控方式

    5、使用步驟:

        1) 開啟瀏覽器輸入目標網址

        2) 進入開發人員工具,選擇效能

        3) 開啟錄製功能,訪問具體介面

        4) 執行使用者行為,一段時間後停止錄製

        5) 分析介面中記錄的記憶體資訊

 

五、如何判斷記憶體的問題

 

    1、記憶體問題的體現

        1) 頁面出現延遲載入或者經常性暫停:頻繁的垃圾回收,程式程式碼產生的垃圾過多

        2)頁面持續性出現糟糕效能表現:記憶體膨脹,當前介面為了達到一定的使用速度,會去申請一定的使用空間,這個空間的大小遠超過我們能夠提供的空間大小

        3) 頁面的效能隨時間延長越來越差:記憶體洩漏,由於某種原因無法被回收的記憶體。

 

    2、界定記憶體問題的標準

        1) 記憶體洩漏:記憶體持續升高

        2) 記憶體膨脹:在多數裝置上都存在效能問題

        3) 頻繁垃圾回收:通過記憶體變化圖進行分析

 

    3、監控記憶體的幾種方式

        1) 瀏覽器工作管理員

            開啟瀏覽器,通過shift+esc開啟工作管理員,右擊開啟JavaScript使用記憶體

            如果小括號裡的記憶體一直增加沒有進行消耗,就存在記憶體洩漏問題

 

        2) Timeline時序圖記錄

            開啟瀏覽器,F12,找到Performance,錄製螢幕,監控記憶體走勢

 

        3) 堆快照查詢分離DOM

            什麼是分離DOM:從當前的DOM樹上脫離了,在JS程式碼中被引用。

            開啟瀏覽器,F12,找到Memory,選擇Profiles=>Heap snapshot=>takeSnapshot=>篩選'deta'就可以得到所有分離DOM

 

        4) 判斷是否存在頻繁的垃圾回收

            當GC工作狀態,應用會假死,如果GC頻繁且過長,使用者會感受到比較差的效能體驗

            Timeline中頻繁的上升下降

相關文章