问题标题 请详谈一下JavaScript的内存回收机制 期望金额10金币 已托管0金币 提问人:138*****763 提问时间:2017-12-18
问题详情
垃圾回收器会每隔一段时间找出那些不再使用的内存,然后为其释放内存。
一般使用标记清除方法  当变量进入环境标记为进入环境,离开环境标记为离开环境
还有引用计数方法


特别要求
其他设置 期望完成时间:2017-12-25
管理员补充 要求回答者擅长领域 网站前端 JavaScript 收藏 我来回答
以下部分为回答内容,共1个回答
1楼

一、垃圾回收机制—GC

Javascript具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存。

原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。

JavaScript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收器会按照固定的时间间隔周期性的执行。

不再使用的变量也就是生命周期结束的变量,当然只可能是局部变量,全局变量的生命周期直至浏览器卸载页面才会结束。局部变量只在函数的执行过程中存在,而在这个过程中会为局部变量在栈或堆上分配相应的空间,以存储它们的值,然后在函数中使用这些变量,直至函数结束,而闭包中由于内部函数的原因,外部函数并不能算是结束。

还是上代码说明吧:

functionfn1() {
 varobj = {name: 'hanzichi', age: 10};//被标记 ,进入环境
}
functionfn2() {
 varobj = {name:'hanzichi', age: 10};//被标记 ,进入环境
 returnobj;
}
vara = fn1();//执行完毕 之后 a、b又被标离开环境,被回收。
varb = fn2();//返回的对象被全局变量b所指向,所以该块内存并不会被释放。


        我们来看代码是如何执行的。首先定义了两个function,分别叫做fn1和fn2,当fn1被调用时,进入fn1的环境,会开辟一块内存存放对象{name: 'hanzichi', age: 10},而当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放;在fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存并不会被释放。

        这里问题就出现了:到底哪个变量是没有用的?所以垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。用于标记的无用变量的策略可能因实现而有所区别,通常情况下有两种实现方式:标记清除和引用计数。引用计数不太常用,标记清除较为常用。

二、标记清除

js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在函数中声明一个变量,就将这个变量标记为“进入环境”。从逻辑上讲,永远不能释放进入环境的变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为“离开环境”。

functiontest(){
 vara = 10 ; //被标记 ,进入环境
 varb = 20 ; //被标记 ,进入环境
}
test(); //执行完毕 之后 a、b又被标离开环境,被回收。


        垃圾回收器在运行的时候会给存储在内存中的所有变量都加上标记(当然,可以使用任何标记方式)。然后,它会去掉环境中的变量以及被环境中的变量引用的变量的标记(闭包)。而在此之后再被加上标记的变量将被视为准备删除的变量,原因是环境中的变量已经无法访问到这些变量了。最后,垃圾回收器完成内存清除工作,销毁那些带标记的值并回收它们所占用的内存空间。

  到目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。

......此处隐藏剩余部分2004字,需支付10金币方可查看...... 购买回答