最近在前端面试的过程中,发现许多公司的基础题中,都会问到垃圾回收机制的相关问题,如说一说浏览器垃圾回收机制的方式,管理内存,如何性能优化。下面就从前端开发的角度解析一下。
一. 什么是垃圾回收器/垃圾回收机制?
垃圾回收机制的原理是找到不再继续使用的变量,释放其内存。垃圾回收器会按照固定的时间间隔(或代码中预定的收集时间),周期性地执行这一操作。
例如函数中局部变量的生命周期,局部变量在函数执行的过程中存在,这时会为局部变量在栈或堆的内存上分配相应的空间,存储他们的值;当函数使用结束时,局部变量没有存在的必要,这时局部变量就没有存在的必要,可以释放他们占用的内存了。垃圾收集器就会跟踪这些变量,判断他是否有用,对于不再使用的打上标记,以备将来收回其内存。一般来说浏览器有两种策略:标记清除和引用计数。
二.垃圾回收机制,浏览器的两种方式:
1.标记清除(主流浏览器做法)
主要思想是给当前不使用的值加上标记,然后再回收他的内存。
垃圾回收器在运行时会给存储在内存中的变量加上标记,然后他会去掉环境变量和被环境变量引用的变量的标记,此后被加上标记的变量(环境变量中没有使用访问的变量)就是准备删除的变量;最后垃圾回收器完成清除工作,销毁那些带标记的值,并回收他们占用的内存空间。
2.引用计数(IE9以下)
含义是跟踪记录所有值被引用的次数。
例如变量a赋值后,这个值的引用次数为1,这个a值又被赋值给另一个变量b,这时引用次数+1;但当b赋另外的值,引用次数-1;当值的引用书为0,说明没有办法再访问这个值,这时就可以将内存回收了。
IE9以下还在使用引用计数,当对象循环引用时,引用次数无法标记为0,就会导致无法被回收。其他浏览器废弃使用。
三.管理内存:
出于安全的考虑,防止运行JavaScript的网页耗尽系统内存导致系统内存崩溃,分配给WEB浏览器可用的内存数量,比分配给桌面应用程序的少。内存的限制问题不仅影响变量的分配内存,还会影响调用栈和在一个线性中同时执行语句的数量。因此,要确保占用最少的内存让页面获得更好地性能。
四.性能优化:
解除引用,也就是一旦数据不再有,最好通过将他设置为null来释放其引用。
解除引用的作用是让值脱离执行环境,以便垃圾回收器下次运行时将其回收。(注:并不是解除引用就能马上回收该值所占的内存)
function createPerson(name){
var localPerson = {};
localPerson.name = name;
}
let globalPerson = createPerson('tom');
// 不使用后手动解除引用
globalPerson = null;
另外可以根据作用域考虑不同变量的放置,尽量少地使用全局变量和闭包。
参考书籍:《JavaScript高级程序设计》