V8垃圾回收机制

调用栈中的数据:

用记录当前执行栈中的指针ESP,指针下移来销毁EC函数执行上下文。就是栈顶移除一个,出栈的过程

堆中的数据:

v8引擎将堆中的区域分为:新生代,老生代,大对象区域(体积超过其他区域的对象,每个对象都有自己的内存),代码区(代码对象,唯一拥有执行权限的内存区域),map区(cell和map,每个区域存放相同大小的元素)

新生代是副垃圾回收器在回收。老生代是主垃圾回收器在回收

副垃圾回收器分为两个区域:对象区域和空闲区域,采用scavenge算法中的Cheney,回收时交换对象区域和空闲区域来回收垃圾

副垃圾回收器里面有晋升策略,如果两次交互依然存在的话,将会将对象复制到老生代中

晋升的条件:必须经历过一次scavenge算法 空闲空间内存占比超过25%

主垃圾回收器:

主垃圾回收器会在内部构建一个根列表。采用mark sweep标记清除

标记清除就是递归遍历根结点,不能够到达就被垃圾回收,最后再将内存归还给操作系统,标记清除会造成不连续的内存碎片

所以后来诞生了mark compact 标记整理算法,他是将活动的对象放到内存的一边,解决了内存碎片的问题

垃圾回收会阻塞主线程的执行。会产生全停顿,

所以诞生了增量标记 increment mark (三色标记法、写屏障 )白色表示垃圾,黑色表示活动对象,灰色表示到哪个位置了

会在浏览器空闲时间进行垃圾回收,然后再把执行权交给js主线程,跟firber机制有点像

v8引擎后继续产生了 lazy sweep 延迟清除,increment compact 增量整理

后利用cpu多核产生了 并行标记,并行清理,减少垃圾回收对主线程的影响

https://juejin.cn/post/6981588276356317214

如何避免内存泄漏?

1.避免在go上绑定一些变量,ECStack执行栈中global context全局可执行上下文不进行释放

2.少用闭包

3.清除定时器

4.清除dom的同时,清除引用,因为dom 清除后,对象的引用内存并没有释放掉

5.weakMap weakSet 其是弱引用,弱引用表示,垃圾回收时不会将健名对该对象的引用考虑进去,只要对象中没有其他引用,垃圾回收机制就会释放掉该对象所占用的内存,不需要手动的进行引用清除

闭包为什么会影响内存泄漏?

1.持有不再需要的函数引用,会导致函数关联的词法环境无法销毁,从而导致内存泄漏

2.当多个函数共享词法环境时,会导致词法环境膨胀,导致无法触达,也无法回收的内存空间

 

posted @ 2021-09-26 16:37  国服第一李师师  阅读(114)  评论(0编辑  收藏  举报