js垃圾回收机制

130 阅读3分钟

js垃圾回收机制

所有全局变量以及全局声明的Array,promise,Object都在内存当中都不是垃圾,因为可能在某一处会用到,如果一个变量没有可能会用到,那就是垃圾

一个局部函数里的变量在调用以后就变成了垃圾,但是在函数调用的时候 因为全局函数引用了 b 所以此时var b 不是一个垃圾

var a=1
function fn (){
    var b=2
}
fn()
console.log(a)

怎样认定是不是一个内存垃圾,如何收集垃圾

当一个对象或者变量没有被引用即可认定为是个垃圾,当然还有一种特殊情况就是引用之间形成闭环也是一种垃圾。 全局声明一个family对象,family对象引用着father和mother对象,mother和father对象也互相引用着,此时将window.family置空,那么就形成了一个闭环

垃圾算法

1.标记-清除-算法mark-swipe算法(整个被浏览一遍) 从全局global遍历看看全局变量或者对象对引用了谁,然后再将这个对象二次遍历一遍,直到没有引用为止,引用的都给一个标记。 缺点是标记起来很慢,假如全局对象有10000个呢 每次都要遍历一边吗? 解决方法 1.将对象分为old和new (generation collection ) 新生代的对象 比如说立即执行函数里面的局部变量,会被例课销毁 old 比方说window对象 他在内存中停留了很久,基本上不会删除(推测) 可以把这种策略归为old代(这是一种策略,当然不一定按照这个) 3s遍历一次 new 执行函数里的 局变量 马上标记马上删除 5ms一次

2.10000个对象分批收集垃圾,每次拟定1000 增量收集 3.空闲时间收集,当js闲下来的时候再执行

面试答题

解释什么是垃圾

没有被引用就是垃圾,还有一种特殊情况就是 三者之间互想被引用,但是没有被其他全局的对象引用到,形成一个闭环也是垃圾

浏览器是如何找到垃圾并把它们删除的? 使用了标记清除算法

从全局对象开始遍历,看看引用了什么,引用到了就标记一下,没有标记的就清除 前端又有特殊的地方,dom和js进程。

<div class="a">xxx</div>
var a=document.querySelector('.a')
a.onclick=function(){

}
settimeout(function(){
a.remove()
// remove只是再节点中删除,但还是存在内存中。如果是a=null呢  会不会在内存中删除?不会因为页面上还是存在一个div,dom,还是存在的/此时的a只是一个变量div,dom元素引用了这个函数
a=null 
// ie有bug  如果dom中没有,但是此dom引用了一个click 会被认为还是存在的
// a.onclick=null  ie
},3000)

引用计数算法

全局对象为1,被引用一次就加1 ,如果为0,那就删除 优点没有必要沿着根集合开始遍历,即刻回收垃圾

参考文章

  1. javascript.info/garbage-col…
  2. www.jianshu.com/p/a8a04fd00…