js垃圾回收機制

conqorld發表於2019-04-16

js的‘樂色’是瀏覽器自動回收的,不需要我們手動釋放記憶體,垃圾收集器會按照固定的時間間隔,週期性的執行這一操作。通常垃圾回收有兩個策略:標記清除和引用計數。

標記清除

當環境變數進入環境時,就將這個變數標記為“進入環境”。從邏輯上講,永遠不能釋放進入環境的變數所佔用的記憶體,因為只要執行流進入相應的環境,就可能會用到他們。而當變數離開環境時,則將其標記為“離開環境”。垃圾收集器在執行的時候會給儲存在記憶體中的所有變數都加上標記。然後,它會去掉環境中的變數以及被環境中的變數引用的標記。而在此之後再被加上標記的變數將被視為準備刪除的變數,原因是環境中的變數已經無法訪問到這些變數了。最後。垃圾收集器完成記憶體清除工作,銷燬那些帶標記的值,並回收他們所佔用的記憶體空間。

目前,使用這種垃圾收集策略的有:chrome、Safari、Opera、IE等。

我將它簡單的理解為瀏覽器每隔一段事件去檢測各個環境內變數是否被外部引用,如果沒有被引用就將其釋放,銷燬私有環境,如果有被外部引用,變數將不能被銷燬,它所處的環境也不能被銷燬。

引用計數

另一種不太常見的垃圾回收策略是引用計數。引用計數的含義是跟蹤記錄每個值被引用的次數。當宣告瞭一個變數並將一個引用型別賦值給該變數時,則這個值的引用次數就是1。相反,如果包含對這個值引用的變數又取得了另外一個值,則這個值的引用次數就減1。當這個引用次數變成0時,則說明沒有辦法再訪問這個值了,因而就可以將其所佔的記憶體空間給收回來。這樣,垃圾收集器下次再執行時,它就會釋放那些引用次數為0的值所佔的記憶體。

這種策略存在一個問題,如果環境中兩個變數相互引用了,那麼他們的計數都會增加,從而無法被銷燬。

手動釋放記憶體

一旦資料不再有用,最好通過將其值設定為null來釋放其引用——這個做法叫做解除引用

例如:

    var obj = {a=2, b=3} 
    obj = null //釋放記憶體
複製程式碼

堆記憶體的釋放:將所有引用堆記憶體空間的地址的變數賦值為null。

棧記憶體的釋放:函式執行完成,所形成的作用域會自動釋放。但是也有特殊情況:1、作用域中的某些內容被外部變數引用了,導致當前棧記憶體無法釋放;2、全域性棧記憶體只有在頁面關閉的時候才會被釋放。

參考:JavaScript高階程式設計(第3版)

相關文章