js垃圾回收和內存泄漏

js垃圾回收和內存泄漏

js垃圾回收

Js具有自動垃圾回收機制。垃圾收集器會按照固定的時間間隔周期性的執行。

1.標記清除(常用)
工作原理:是當變量進入環境時,將這個變量標記為「進入環境」。當變量離開環境時,則將其標記為「離開環境」。標記「離開環境」的就回收內存。
工作流程:
1.垃圾回收器在運行的時候會給存儲在內存中的所有變量都加上標記。
2.去掉環境中的變量以及被環境中的變量引用的變量的標記(閉包)。
3.依然被標記的會被視為準備刪除的變量。
4.垃圾回收器完成內存清除工作,銷毀那些帶標記的值並回收他們所佔用的內存空間。

2.引用計數
跟蹤記錄每個值被引用的次數
工作流程:
1.聲明了一個變量並將一個引用類型的值賦值給這個變量,這個引用類型值的引用次就是1。
2.同一個值又被賦值給另一個變量,這個引用類型值的引用次數加1.
3.當包含這個引用類型值的變量又被賦值成另一個值了,那麼這個引用類型值的引用次數減1.
4.當引用次數變成0時,說明沒辦法訪問這個值了。
5.當垃圾收集器下一次運行時,它就會釋放引用次數是0的值所佔的內存。

內存泄漏

使用了內存之後, 如果後面他們不會再被用到,但是還沒有及時釋放,這就叫做內存泄露(memory leak)。如果出現了內存泄露,那麼有可能使得內存越來越大,而導致瀏覽器崩潰。
引起內存泄漏的情況:

  1. 意外的全局變量引起的內存泄漏。
function foo(arg) {
    bar = "this is a hidden global variable"; // 沒有用var
  }


 function foo() {
    this.variable = "potential accidental global";
  }
  // 一般函數調用,this指向全局

原因:全局變量,不會被回收。

解決:使用嚴格模式避免,函數內使用var定義,塊內使用let、const。
2. 閉包引起的內存泄漏
原因:閉包可以維持函數內局部變量,使其得不到釋放。

解決:將事件處理函數定義在外部,解除閉包,或者在定義事件處理函數的外部函數中,刪除對dom的引用。