三分钟快速理解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)
相关文章
相关标签/搜索