挑战前端基础120题--垃圾回收机制?
1. 什么是垃圾回收机制?
简称GC,内存管理自动运行,找到不被使用的变量,进行垃圾回收 释放内存;
补充点:JS变量分为:全局变量 & 局部变量; 全局变量的生命周期是一直存在直到页面被销毁。局部变量一般定义在函数内部,他的生命周期从函数被调用开始,直到函数运行结束。等到局部变量不被使用,就会被释放从而被垃圾回收;
2.为什么要进行垃圾回收?
为了防止内存泄漏,造成程序卡顿和奔溃;一般分为:意外的全局变量(对象的形式存在),被忘记的定时器或者回调函数,闭包,DOM泄漏;
3.如何实现?
2种实现方案:清除标记法 & 引用计数法
清除标记法:简单来说 垃圾回收机制会被所有不被使用的变量打上标记,然后回收他的内存;这也是大对数浏览器采用的方法;
- 先找出所有的根结点(全局变量);
- 运用算法 将所有的根结点 & 他们的字节点 标记为活跃。任何根结点不能访问的变量统一标记为垃圾;
- 垃圾收集器释放所有未被标记为活跃的内存块,并将这些内存返回给操作系统;
优点:实现简单 无非就是标记和不标记
缺点:1. 内存碎片: 垃圾回收完后 剩余分配的变量内存空间位置不变,会导致剩余的内存空间变量不连续。出现内存碎片。
2.分配新内存缓慢:当有一个新的变量需要分配内存size时,需要遍历剩余内存碎片,直到找到合适的size才会进行分配;有可能需遍历全部,还不一定能分配上;
后面新出的标记整理算法:和标记清除没有什么区别,只是在垃圾回收完后将剩余的变量 空间统一移动到一侧,解决了内存碎片的问题;
引用计数法:是判断有无引用指向该对象的地址,引用一次+1,等于0的就被回收;
优点:相比清除标记灵活,清除标记需要隔一段时间运行一次。 引用标记只要被标记为0就会自动被回收。
缺点:对象相互引用的时候(循环引用),即使后来不被使用了 也永远不会被标记为0。并且计数的方式需要一个计算器,占用内存位置。
4.v8引擎对于GC做了什么优化?
V8为了优化GC的全暂停时间,还引入了 增量标记 、 并发标记 、 并行标记 、 增量整理 、 并行清理 、 延迟清理 等方式。
5.深入:new Map()为什么也能被垃圾回收机制回收?
在JavaScript中, Map 对象存储的是键值对,其中键和值都可以是任何类型。 然而, Map 并不阻止其键(或值)被垃圾回收。 当没有其他引用指向一个对象时,该对象就可能被垃圾回收机制回收