一、記憶體管理
JavaScript 是一種自動垃圾回收語言,這意味著 JavaScript 引擎會自動監測和清理無用的記憶體,
JavaScript 中的記憶體管理主要由 JavaScript 引擎負責,開發人員不需要手動管理記憶體,JavaScript 引擎使用垃圾回收演算法來實作自動垃圾回收,
二、垃圾回收
JavaScript 垃圾回收演算法是指在 JavaScript 程式中,用來回收不再使用的記憶體的演算法,常見的垃圾回收演算法包括:
- 標記-清除演算法:標記出所有不再使用的物件,然后清除它們,
- 參考計數演算法:維護每個物件的參考計數,當計數為0時回收物件,
- 標記-整理演算法:標記出所有不再使用的物件,然后將所有存活的物件整理到一起,回收其他物件,
- 增量標記-整理演算法:將垃圾回收程序分成多個小步驟執行,并且可以處理回圈參考問題,
現代 JavaScript 引擎通常采用增量標記-整理演算法或其他類似演算法來實作垃圾回收,
1、標記-清除演算法
標記-清除演算法是通過標記未使用的記憶體塊,然后清除這些標記的記憶體塊來實作垃圾回收的,
標記-清除演算法的作業流程如下:
- 從根節點開始,遍歷所有可達的物件,將其標記為“可用”,
- 掃描記憶體中所有物件,將未被標記的物件標記為“不可用”,
- 清除所有不可用物件占用的記憶體,
標記-清除演算法的優缺點
優點:
- 標記-清除演算法簡單易實作,
- 標記-清除演算法可以回收任意型別的物件,
缺點:
- 標記-清除演算法會產生碎片化的記憶體,這可能導致空間浪費,
- 標記-清除演算法會產生暫停,這可能導致程式卡頓,
現在,由于標記-清除演算法會產生碎片化的記憶體和暫停,所以現代的 JavaScript 引擎主要使用增量標記-整理演算法來實作垃圾回收,增量標記-整理演算法將垃圾回收程序分成多個小步驟執行,避免了長時間的暫停,
標記-清除演算法是一種簡單易實作的垃圾回收演算法,但是會產生碎片化的記憶體和暫停,因此現在不再常用,
2、參考計數演算法
參考計數演算法是通過跟蹤每個物件的參考次數來確定物件是否被使用,如果一個物件的參考次數為0,則該物件被視為垃圾并被回收,
參考計數演算法的作業流程如下:
- 每當一個物件被參考時,將其參考計數增加1,
- 每當一個物件的參考被洗掉時,將其參考計數減少1,
- 當一個物件的參考計數為0時,該物件被視為垃圾并被回收,
參考計數演算法的優缺點
優點:
- 參考計數演算法可以實時回收垃圾,
- 參考計數演算法可以較快地回識訓圈參考的物件,
缺點:
- 參考計數演算法無法處理回圈參考問題,如果兩個物件相互參考,而沒有其他變數參考它們,則它們的參考計數都為1,而它們都不能被回收,
- 參考計數演算法會增加程式的運行時間和空間開銷,
參考計數演算法在處理回圈參考問題上會有困難,而且參考計數演算法會增加程式的運行時間和空間開銷,因此現代的 JavaScript 引擎不再使用參考計數演算法來實作垃圾回收,
參考計數演算法的實作方式可以是各種各樣的, 例如:
- 對于每一個物件都維護一個計數器,在有新的參考時將計數器加一,在參考結束時將計數器減一,
- 對于每一個物件維護一個參考鏈表,在有新的參考時將參考的物件加入鏈表中,在參考結束時將參考的物件移除鏈表,
雖然現在的 JavaScript 引擎不再使用參考計數演算法來實作垃圾回收,但是對于參考計數演算法的理解對于理解其他演算法有很大幫助,
3、標記-整理演算法
標記-整理演算法是一種垃圾回收演算法,它首先標記出所有不再使用的物件,然后將所有存活的物件整理到一起,回收其他物件,
標記-整理演算法的作業流程如下:
- 標記:從根節點開始,遍歷所有可達的物件,將其標記為“存活”,
- 整理:將所有存活的物件移動到一起,以便進行回收,
- 回收:回收所有未被標記的物件占用的記憶體,
標記-整理演算法的優缺點
優點:
- 可以有效地處理回圈參考問題,
- 可以減少記憶體碎片化,
缺點:
- 整理程序會影響性能,
- 需要額外的空間來存盤活動物件和空閑物件,
標記-整理演算法在處理回圈參考問題上會有優勢,減少記憶體碎片化,但是會影響性能,需要額外的空間來存盤活動物件和空閑物件,
標記-整理演算法是一種較為新的垃圾回收演算法,相對于標記-清除演算法和參考計數演算法而言,它可以更好地解決回圈參考問題,
在使用標記-整理演算法進行垃圾回收時,系統會標記出所有仍然在使用的物件,然后將這些物件移動到一起,這樣就可以避免記憶體碎片化,并且可以減少回圈參考問題的影響,
但是,標記-整理演算法也有缺點,整理程序會影響性能,需要額外的空間來存盤活動物件和空閑物件,另外,在 JavaScript 引擎中,這種演算法也沒有得到廣泛采用,大多數 JavaScript 引擎使用的是增量標記-整理演算法或其他類似演算法,
4、增量標記-整理演算法
現代的 JavaScript 引擎主要使用增量標記-整理演算法來實作垃圾回收,這種演算法在運行時將垃圾回收程序分成多個小步驟來執行,避免了長時間的暫停,
增量標記-整理演算法的作業流程如下:
- 標記:從根節點開始,遍歷所有可達的物件,將其標記為“存活”,
- 整理:將所有未被標記的物件移動到一起,以便進行回收,
- 回收:回收所有未被標記的物件占用的記憶體,
增量標記-整理演算法通過將垃圾回收程序分成多個小步驟執行,來避免了長時間的暫停,這樣可以在不影響用戶體驗的情況下進行垃圾回收,
增量標記-整理演算法的優缺點
優點:
- 避免了長時間的暫停,提高了程式的回應性,
- 增量標記-整理演算法可以有效地處理回圈參考問題,
缺點:
- 由于增量標記-整理演算法是一種標記-整理演算法,所以會產生碎片化的記憶體,這可能降低記憶體利用率,
- 增量標記-整理演算法的實作需要額外的空間來存盤活動物件和空閑物件,
增量標記-整理演算法是基于標記-清除演算法和標記-整理演算法的結合體,它首先使用標記-清除演算法找出所有存活的物件,然后使用標記-整理演算法將這些物件移動到一起,以便進行回收,
三、優化措施
JavaScript 中針對垃圾回收的優化措施有很多,主要有如下幾種:
-
避免回圈參考:回圈參考是 JavaScript 垃圾回收中常見的問題,為了避免這種問題,開發人員應該盡量避免在不同物件之間建立回圈參考關系,
-
盡早釋放不再使用的物件:盡早釋放不再使用的物件可以減少垃圾回收的作業量,進而提高性能,例如,在不再使用的時候將變數賦值為 null 或 undefined,可以幫助 JavaScript 引擎更快地找到垃圾,
-
避免使用全域變數:全域變數會一直存在,如果不需要使用,就應該盡早釋放,
-
避免使用長作用域鏈:長作用域鏈會導致 JavaScript 引擎花費更多的時間來跟蹤物件的存活狀態,因此應該盡量避免使用長作用域鏈,
-
使用 WeakMap 和 WeakSet:WeakMap 和 WeakSet 可以幫助我們維護物件之間的弱參考關系,可以減少回圈引,
-
使用 requestIdleCallback:requestIdleCallback 允許我們在瀏覽器空閑時執行一些任務,可以幫助我們在不影響用戶體驗的情況下進行垃圾回收,
需要注意的是,JavaScript 中的垃圾回收并不能保證程式一定不會出現記憶體泄漏的情況,例如回圈參考,開發人員需要知道這種情況并采取對應的處理措施,
應對回圈參考問題的處理措施?
JavaScript 中的回圈參考是指兩個或多個物件之間相互參考的情況,這種情況下,這些物件就不能被垃圾回識訓制正常回收,會導致記憶體泄漏,
解決回圈參考問題主要有以下幾種方法:
-
使用 WeakMap 和 WeakSet:WeakMap 和 WeakSet 可以幫助我們維護物件之間的弱參考關系,可以減少回圈參考問題,
-
使用計數器:對于某些情況,通過維護物件之間的參考計數可以幫助我們解決回圈參考問題,
-
使用雙向鏈表:雙向鏈表可以幫助我們解決回圈參考問題,可以支持物件之間相互參考,但是需要手動維護物件之間的關系,
-
避免回圈參考:是最簡單而有效的解決辦法,開發人員應該盡量避免在不同物件之間建立回圈參考關系,
-
使用第三方庫:使用第三方庫也可以幫助我們解決回圈參考問題,如 cycle.js
-
使用設定空值的方法:在不再使用某個物件時,將其設定為空值可以消除對該物件的參考,
-
使用閉包:閉包可以在函式執行結束后銷毀其所參考的物件,
-
使用 IIFE:IIFE(立即執行函式運算式)可以在函式執行結束后立即銷毀其所參考的物件,
-
使用 WeakRef:WeakRef是一種弱參考物件,它不會影響到物件的存活狀態,可以使用它來消除回圈參考,
需要注意的是, 在使用這些方法解決回圈參考問題時, 還需要考慮到代碼復雜度和可維護性, 在使用時應該慎重考慮,
JavaScript 中沒有強制垃圾回收的方法,也沒有手動釋放記憶體的方法, JavaScript 引擎會根據需要自動進行垃圾回收,
在 JavaScript 中,當一個物件不再被任何變數參考時,它就會被視為垃圾并被回收,需要注意的是,JavaScript 中的垃圾回收僅針對不再使用的記憶體,而不是不再使用的變數,例如,如果一個變數存盤的是物件的參考,則該物件可能不再被其他變數參考,但仍然可能被使用,
總之,JavaScript 中的記憶體管理主要由 JavaScript 引擎負責,開發人員不需要手動管理記憶體,JavaScript 中的垃圾回收是自動進行的,開發人員只需要了解垃圾回識訓制并采取優化措施,就可以幫助程式更好的管理記憶體,
作者:yuzhihui出處:http://www.cnblogs.com/yuzhihui/ 宣告:歡迎任何形式的轉載,但請務必注明出處!!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/542353.html
標籤:其他
