一、什么是JavaScript垃圾回收机制
JavaScript中的垃圾回收机制是自动管理内存的一种机制。它负责在程序运行时识别和清除不再使用的内存,以便释放资源并提高性能。
JavaScript中的垃圾回收器会定期扫描内存中的对象,标记那些可达对象和不可达对象。
可达对象指的是当前代码中正在被使用的对象
不可达对象指的是已经不再被引用的对象。
JavaScript中的垃圾回收机制主要有两种:
标记清除(Mark-and-Sweep)
引用计数(Reference Counting)
二、标记清理(重点)
垃圾回收程序运行时,会标记内存中存储的所有变量(标记方法有多种).然后他会将所有在作用域的变量,以及被变量引用的变量的标记去掉.在此之后,被标记的变量就等待被删了.随后垃圾回收机制会运行一次,清理标记的值且收回被占用的内存。
let a =10
let b =a;
如今,IE,Chrome,Opera,Firfox都在使用标记清理,只是其回收的频率上,略有差别。
标记清理是最基本的垃圾扫除算法,首先我们从global也就是window出发,开始去找它每一个指向,然后找到所有能根据指向找到的变量,我们给这样的变量一个:√。其他找不到的标记为:×。最后清除所有为×的变量
这个基础算法有很多的缺点:
标记的效率太慢了,我们的垃圾回收需要时时刻刻去遍历检查每一个引用,如果你的js代码中对象太多,会导致非常严重的效率问题
浏览器在标记的过程中js是不能执行的,我们不能让垃圾回收拖慢我们js运行的时间
这里针对标记扫除有三个优化点:
分代垃圾回收:我们可以将对象分为新生代和老生代,两者我们采用不同的回收策略。比如说window对象,就像个老祖宗一样,你这些后代是不是要时常像老祖宗请教?所以我们对于老一代可以回收的不那么勤快(全局变量),隔几秒钟去遍历一次就行啦。对于新生代(局部变量),我们需要马上标记马上回收。
增量执行:不会一次就全部遍历完,可能一次遍历个十分之一,提高性能
空余时间执行,比如我可以在你js执行完了之后再执行,不会影响到js的执行效率
三、引用计数(了解)
它的工作原理是:垃圾回收器会记录每个对象被引用的次数,当对象被引用的次数为0时,就将该对象清除。该算法的优点是实现较为简单,但无法处理循环引用的情况,可能会导致内存泄漏。
引用计数因为弊端太多已经被放弃。
四、代码优化
解除引用:尽量少的占用内存,可以让页面性能更好.这就要求我们在运行时,只保存必要的数据.若数据不再需要就设置为null,解除引用.解除引用不会自动触发垃圾回收机制,但能确保相关的值,已经不在作用域.因此下次垃圾回收时,将会被回收.
性能提升:
let 和const 都以块为作用域( {} ),非函数.最大作用域为
尽量将变量都写在局部作用域中或函数中,块级作用域{} 中,方便回收 { let str = 123; }
减少内存泄漏:局部变量记得声明(不声明会默认var到全局去);减少定时器的使用