推荐阅读:《JS 闯关记》之垃圾回收和内存管理
常见的垃圾回收有2种策略:标记清除 和 引用计数
标记清除
会遍历堆中所有的对象,然后标记活的对象,在标记完成后,销毁所有没有被标记的对象。
在标记大型对内存时,可能需要几百毫秒才能完成一次标记。这就会导致一些性能上的问题。
为了解决这个问题,2011 年,V8 从 stop-the-world 标记切换到增量标志。在增量标记期间,GC 将标记工作分解为更小的模块,可以让 JS 应用逻辑在模块间隙执行一会,从而不至于让应用出现停顿情况。
但在 2018 年,GC 技术又有了一个重大突破,这项技术名为并发标记。该技术可以让 GC 扫描和标记对象时,同时允许 JS 运行,你可以点击 该博客 详细阅读。
引用计数
声明一个变量,并将一个引用类型值赋给该变量,那么这个值的引用次数就是1,同理,之后如果还有变量引用它,引用次数会+1,变量取消引用的话引用次数减1。
等到垃圾回收执行的时候,垃圾回收器会把引用次数为0的变量回收。
ps: 早期很多浏览器使用引用计数策略,但是后来出现循环引用的问题,现代浏览器都纷纷采用标记清除法了
优化代码策略
我们往往会遇到一些内存泄露的问题,就是一些变量我们不在用了,但是还是保留着。最常见的就是一些全局变量和一些闭包变量,我们应该尽可能的把不需要再用到的变量置空。
例如本来let a = {name: 'rick'},我们不要的用的时候把a = null。这样下次执行垃圾回收的时候,垃圾回收器就会把{name: 'rick'}占用的空间给释放。