垃圾回收
狐七 3/30/2022 render
# 1. 聊聊什么是内存管理?
查看答案
内存管理是开发者主动申请空间、使用空间、释放空间的过程。
js中基本数据类型(栈空间)由操作系统自动分配释放,引用类型(堆空间)由开发者分配释放。
# 2. 什么是内存泄露?
查看答案
内存泄露是空间不再使用缺没有释放的现象,会导致程序缓慢或崩溃。
一般不当使用闭包会导致内存泄露。
解决:
js中解决此类问题需要在使用完成后主动将变量置为null
# 2. 什么是垃圾回收机制
查看答案
GC是垃圾回收机制的简写,根据GC算法找到内存中的垃圾,并释放和回收空间
- GC垃圾:程序中 不再需要使用的,程序中不能再访问的 对象
- GC算法:垃圾回收查找垃圾和回收所遵循的规则
# 3. 常见的GC算法有哪些?
查看答案
- 引用计数
- 标记清除
- 标记整理
- 分代回收(V8用到的)
# 4. 引用计数的原理是什么?优缺点有哪些?
查看答案
原理:
- 引用计数器,引用改变时修改引用数字
- 判断当前引用数是否为0来决定是不是垃圾对象,如果是垃圾对象就进行回收
优点:
- 发现垃圾时立即回收
- 最大限度减少程序暂停,让空间不会有被占满的时候
缺点:
- 无法回收循环引用的对象
- 资源消耗开销大(对所有对象进行数值的监控和修改,本身就会占用时间和资源)
# 5. 标记清除的原理是什么?优缺点有哪些?
查看答案
原理:
- 标记阶段:遍历所有对象找活动对象(可达对象)标记(层次用递归进行操作)
- 清除阶段:遍历多有对象清除没有标记对象并抹掉第一个阶段标的标记
- 回收相应空间,将回收的空间加到空闲链表中,方便后面的程序申请空间使用
优点:
- 相对于引用计数算法来说解决对象循环引用的问题,局部作用域里面的内容无法被标记,所以即使有引用还是会被清除掉
缺点:
- 空间链表地址不连续(空间碎片化),不能进行空间最大化使用
- 不会立即回收垃圾对象,清除的时候程序是停止工作的。
# 6. 标记整理的原理是什么?优缺点有哪些?
查看答案
原理:
标记整理可以看做是标记清除的 增强
- 标记阶段:遍历所有对象找活动对象(可达对象)标记(层次用递归进行操作)
- 整理阶段:清除前先执行整理,移动对象位置,在地址上产生连续
- 清除阶段:遍历多有对象清除没有标记对象并抹掉第一个阶段标的标记
- 回收相应空间,将回收的空间加到空闲链表中,方便后面的程序申请空间使用
优点:
- 相较标记清除算法减少了碎片化空间
缺点:
- 不会立即回收垃圾对象,清除的时候程序是停止工作的。
# 7. PHP中如何解决引用计数循环引用的问题?
查看答案
- PHP把变量使用unset后计数器不为0的变量看做疑似垃圾变量,记录在垃圾缓冲区中
- 执行时机:当缓冲区满时会进行一次垃圾检查
- 模拟删除,递归模拟删除缓冲区的变量,使他们的计数器-1并且标记
- 模拟恢复,递归将所有标记的变量不为0的+1恢复
- 真实删除,将计数器为0的数据真实删除
如果一个变量只被自己引用,那么在unset之前的计数器是2,执行unset之后计数器为1,此时会被看做疑似垃圾变量。执行模拟删除之后计数器就会为0,此时就会进行真实删除。
# 8. 聊聊什么是JS垃圾回收机制
查看答案
- JS的内存管理是自动的,每当我们创建对象、数组等,它就会自动的跟配内存空间。
- 对象不再被引用时,或者对象已经存在,但是这些对象不能从根上访问(全局变量对象) 到时是垃圾。
- 这个时候JavaScript会自动对这些垃圾进行空间的释放和回收,即JavaScript的垃圾回收。
- js的垃圾回收依赖浏览器的垃圾回收机制。
# 9. V8的垃圾回收机制
查看答案
原始类型数据的回收由程序语言自身控制的,这里主要讨论的是存活在堆区的对象数据,这个过程是离不开内存操作的。
主要采用:
- 采用分代回收的思想
- 内存分为新生代存储区、老生代存储区
- 新生代区域主要存储存活时间较短的对象,老生代区域主要存储存活时间较长的对象
- 针对不同代采用不同的算法
- 新生代的主要算法有:复制算法+标记整理法
- 主要用空间换时间
- 新生代区域分为两个大小的from和to空间
- from空间是存活动对象,to是空闲空间
- from使用到一定程度就会触发GC标记整理并将活动对象拷贝到to空间
- 触发from空间回收
- 将from和to空间进行名称调换重复上面的操作
- 老生代的主要算法有:标记清除+标记整理+增量标记法
- 增量标记:将一整段的垃圾回收操作标记拆分成多个小段完成回收,主要是为了实现程序和垃圾回收的交替完成,这样进行效率优化带来的时间消耗更加的合理。目前V8垃圾回收采用增量标记算法需要50ms,采用非增量标记算法需要1s。
- 首要采用标记清除法,速度快。
- 在晋升的时候,老生代的空间不够用的时候,会进行标记整理法。
- 新生代的主要算法有:复制算法+标记整理法
- 一定机制下,新生代会向老生代区域晋升
- 一轮GC之后还存活的对象要进行晋升
- 拷贝过程中,to空间使用率超过25%时会全部晋升