js垃圾回收和記憶體泄漏
- 2020 年 9 月 13 日
- 筆記
- js垃圾回收和記憶體泄漏, 面試題📃
js垃圾回收和記憶體泄漏
js垃圾回收
Js具有自動垃圾回收機制。垃圾收集器會按照固定的時間間隔周期性的執行。
1.標記清除(常用)
工作原理:是當變數進入環境時,將這個變數標記為「進入環境」。當變數離開環境時,則將其標記為「離開環境」。標記「離開環境」的就回收記憶體。
工作流程:
1.垃圾回收器在運行的時候會給存儲在記憶體中的所有變數都加上標記。
2.去掉環境中的變數以及被環境中的變數引用的變數的標記(閉包)。
3.依然被標記的會被視為準備刪除的變數。
4.垃圾回收器完成記憶體清除工作,銷毀那些帶標記的值並回收他們所佔用的記憶體空間。
2.引用計數
跟蹤記錄每個值被引用的次數
工作流程:
1.聲明了一個變數並將一個引用類型的值賦值給這個變數,這個引用類型值的引用次就是1。
2.同一個值又被賦值給另一個變數,這個引用類型值的引用次數加1.
3.當包含這個引用類型值的變數又被賦值成另一個值了,那麼這個引用類型值的引用次數減1.
4.當引用次數變成0時,說明沒辦法訪問這個值了。
5.當垃圾收集器下一次運行時,它就會釋放引用次數是0的值所佔的記憶體。
記憶體泄漏
使用了記憶體之後, 如果後面他們不會再被用到,但是還沒有及時釋放,這就叫做記憶體泄露(memory leak)。如果出現了記憶體泄露,那麼有可能使得記憶體越來越大,而導致瀏覽器崩潰。
引起記憶體泄漏的情況:
- 意外的全局變數引起的記憶體泄漏。
function foo(arg) {
bar = "this is a hidden global variable"; // 沒有用var
}
function foo() {
this.variable = "potential accidental global";
}
// 一般函數調用,this指向全局
原因:全局變數,不會被回收。
解決:使用嚴格模式避免,函數內使用var定義,塊內使用let、const。
2. 閉包引起的記憶體泄漏
原因:閉包可以維持函數內局部變數,使其得不到釋放。
解決:將事件處理函數定義在外部,解除閉包,或者在定義事件處理函數的外部函數中,刪除對dom的引用。