JavaScript的垃圾回收機制


原理找出不使用的變量釋放內存

JavaScript是使用垃圾回收的語言,也就是很大的解決了跟蹤內存對開發者造成的負擔(畢竟這是很多問題的來源)。而卸下這個甜蜜的負擔(一點也不甜蜜好嘛),通過自動內存管理實現內存分配和閑置資源回收。下面會簡單的講述內存泄漏

如果不用垃圾回收機制會造成什么后果

1.會消耗掉所有的可用內存內存占用),造成系統崩潰

2.內存泄漏

可達性一個地方到另一個地方的容易程度

GC的最主要的職責是監控數據的可達性

1.所有顯示調用被稱為根全局對象

  正被調用的函數的局部變量參數

  相關嵌套函數里的變量和參數

  其他引擎內部調用的一些變量

2.所用從根引用或引用鏈訪問的對象

什么時候觸發垃圾回收機制

該過程是周期性的每隔一個固定的時間就會自動運行程序

如果分配的內存非常多回收工作也會很艱巨確定垃圾回收時間間隔就變成了值得思考的問題

垃圾回收的基本思路:

該過程是周期性的,每隔一個固定的時間,就會自動運行程序。這是一個不能稱之為完美的方案,畢竟算法不能夠准確的知道,我們到底是否需要該變量。

下面以一個函數中局部變量的正常生命周期為例。函數中的局部變量會在函數執行時存在。

 

 此時該變量已經不在需要,占用的內存可以釋放,以供后者使用。所以垃圾回收機制需要跟蹤標記變量,並判定是否使用。如何標記未使用的變量也許有不同的實現方式。但是在瀏覽器里面的話有兩種常用的方式:標記清理和引用計數。

標記清理

在JavaScript中最常用的垃圾回收策略是標記清理(mark-andsweep)。當變量進入上下文,比如:

而不在上下文中的變量,邏輯上講,永遠不應該釋放它們的內存,因為只要上下文中的代碼在運行,就有可能用到它們。

就算變量離開了上下文,也會做出標記。

 給變量加標記的方式有很多種。比如,當變量進入上下文時,反轉某一位;或者可以維護“在上下文中”和“不在上下文中”兩個變量列 表,可以把變量從一個列表轉移到另一個列表。標記過程的實現並不重要,關鍵是策略。

垃圾回收程序運行的時候,會標記內存中存儲的所有變量。然后,它會將所有在上下文中的變量,以及被在上下文中的變量引用的變量的標記去掉。在此之后再被加上標記的變量就是待刪除的了,原因是任何在上下文中的變量都訪問不到它們了。隨后垃圾回收程序做一次內存清理,銷毀帶標記的所有值並收回它們的內存。

引用計數

上文提到的第二種垃圾回收機制。另一種沒那么常用的垃圾回收策略是引用計數(reference counting)。

其思路是對每個值都記錄它被引用的次數。聲明變量並給它賦一個引用值時,這個值的引用數為1。如果同一個值又被賦給另一個變量,那么引用數加1。類似地,如果保存對該值引用的變量被其他 值給覆蓋了,那么引用數減1。當一個值的引用數為0時,就說明沒辦 法再訪問到這個值了,因此可以安全地收回其內存了。垃圾回收程序 下次運行的時候就會釋放引用數為0的值的內存。

為什么現在使用引用計數的比較少該方法無法解決循環引用問題A引用B同時B引用A相互應用會導致內存泄漏

反反復復提到的內存泄漏是什么

內存泄漏

是指程序上動態的分配的堆內存由於某種原因程序未釋放或無法釋放造成系統的浪費導致程序的運行速度減慢甚至系統崩潰等嚴重后果

缺陷具有隱蔽性積累性的特性比其他內存非法訪問錯誤

在內存中共用戶使用的內存空間分為3部分

1.程序存儲區

2.靜態存儲區 

3.動態存儲區

JavaScript中的內存管理

內存由可讀寫單元組成表示一片可操作和內存條中的內存同理

管理人為的去操作一片空間的申請使用和解放

內存管理開發者主動申請空間使用空間釋放空間

管理流程申請-使用-釋放

JavaScript內存空間分配

變量  基礎數據類型值有固定大小閉包除外

復雜的對象  引用數據類型的大小是不固定的引用數據類型的值保持在堆內存的變量中

常量

JavaScript不允許直接訪問堆內存中的位置

實際上在操作對象的引用而不是實際的對象

 

小結

JavaScript是使用垃圾回收的編程語言,開發者不需要操心內存分配和回收。JavaScript的垃圾回收程序可以總結如下。

離開作用域的值會被自動標記為可回收,然后在垃圾回收期間被刪除。

主流的垃圾回收算法是標記清理,即先給當前不使用的值加上標記,再回來回收它們的內存。

引用計數是另一種垃圾回收策略,需要記錄值被引用了多少次。

JavaScript引擎不再使用這種算法,但某些舊版本的IE仍然會受這種算法的影響,原因是JavaScript會訪問非原生JavaScript對象(如 DOM元素)。

引用計數在代碼中存在循環引用時會出現問題。

解除變量的引用不僅可以消除循環引用,而且對垃圾回收也有幫助。

為促進內存回收,全局對象、全局對象的屬性和循環引用都應該在不需要時解除引用

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM