三分鐘快速理解javascript內存管理

javascript中具備垃圾自動回收機制(Garbage Collection),也就是執行環境會負責管理代碼執行過程當中使用的內存,在開發過程當中就能夠不考慮內存的分配,以及無用內存釋放的問題.可是觸發當即回收機制會中斷代碼的執行,中止其餘操做,遍歷全部的對象,回收全部不可訪問的對象,所以垃圾回收的工做機制是週期性的.javascript

因本文爲快速理解內存管理因此相關涉及的知識:做用域鏈,閉包等概念我在這裏就不作展開,想要去了解的朋友能夠直接在掘金上瀏覽相關文章,有不少大牛的優秀文章值得一讀java

變量的生命週期

你們都知道javascript有做用域的概念,在局部做用域內用var關鍵字聲明變量,函數執行結束,若是垃圾回收機制判斷到此局部變量能夠被回收,那麼這個局部變量就會在內存中消失.閉包

function fn1(){
        var obj = {name: 'richard'}
    }
    function fn2(){
        var obj = {name: 'jungkkki'}
        return obj
    }
    var a = fn1() // undefined
    var b = fn1() // {name: 'jungkkki'}
複製代碼

fn1在函數內聲明瞭局部變量obj而且賦值,在函數執行結束後,這個局部變量便再也沒法訪問到了,當垃圾回收機制週期性運行時,這個局部變量obj將被回收.函數

fn2在函數內聲明瞭局部變量obj而且賦值,在函數執行結束後,這個局部變量返回值賦值給全局變量b,當垃圾回收機制週期性運行時,{name:'jungkkki'}的內存不會被回收.優化

分享知識點:解釋型語言(例如 JavaScript)來講, 經過詞法分析 -> 語法分析 -> 語法樹,就能夠開始解釋執行了。
語法分析成 AST (Abstract Syntax Tree),你們能夠在這裏試試 http://esprima.org/
spa

標記清除&引用計數

javascript如何來判斷變量是否能夠被訪問那麼就要提到辣雞回收機制中標記清除和引用計數3d

function test(){
       var one = {num: '1'} // 標記進入環境
       var two = {num: '2'} // 標記進入環境
   }
   test() // 函數執行完畢 one,two 標記離開環境
複製代碼

標記清除:一般javascript經過標記變量的狀態來判斷是否被回收,當變量在函數中被聲明時標記進入環境,在函數執行結束時,環境被銷燬標記離開環境等待回收.只要不釋放進入環境的變量,他在環境中的任何位置任什麼時候刻均可以被訪問,就不會被垃圾回收機所回收.code

function test2(){
       var a = {name: 'richard'} // {name: 'richard'} 引用次數1
       a = {name: 'jungkkki'} // {name: 'richard'} 引用次數 -1 直接標記,等待回收 {name; 'jungkkki'} 引用次數+1
   }
   test() // 函數執行結束 環境銷燬 {name: 'jungkkku'}等待回收
複製代碼

引用計數:javascript去維護一張表,存儲內存中資源的引用次數,資源被引用+1,結束引用或者函數執行完畢結束做用域,引用次數-1,引用次數由1到0時不會執行,節省開銷,直接標記cdn

GC 的缺陷、分代回收和增量 GC

和其餘語言同樣 GC 會中斷代碼執行,中止其餘操做。由於要遍歷全部對象,回收全部不可訪問對象,這個操做的耗時可能有 100ms 以上。在 V8 引擎新版本中引入了兩種優化方法:1. 分代回收(Generation GC),2. 增量 GC(increment GC)對象

分代回收:目的是經過對象的使用頻率、存在時長區分新生代與老生代對象。多回收新生代區(young generation),少回收老生代區(tenured generation),減小每次需遍歷的對象,從而減小每次GC的耗時

增量 GC:把須要長耗時的遍歷、回收操做拆分運行,減小中斷時間,可是會增大上下文切換開銷.

喜歡的朋友能夠隨手點贊和關注,有你們的支持就有了更多的動力

![](https://user-gold-cdn.xitu.io/2017/10/23/c7095c96db3d54b6d71c17e48fcc3cb0)
相關文章
相關標籤/搜索