1.垃圾回收分两种:手动回收,自动回收

    • c/c++就是手动回收策略,内存分配,销毁都是代码控制
    • 垃圾回收器收集垃圾,不需要手动通过代码

    2.记录当前执行状态的指针就是esp,js引擎会移动ESP来销毁该函数保存在栈中的上下文,原始数据类型也会被销毁,但是
    image.png
    堆里面的引用数据类型仍然存在

    image.png

    3.堆分为新生代跟老生代的区域

    • 新生代:存放生存时间短的对象,1-8m的容量
    • 老生代:存放生存时间长的对象
    • 副垃圾回收器:回收新生代垃圾
    • 主垃圾回收器:回收老生代垃圾

    4.执行流程

    • 了解代际假说,分代收集
    • 标记空间中活动对象,非活动对象,非活动对象就是可以进行垃圾回收对象
    • 回收非活动对象占据的内存,清理内存中标记为可回收对象
    • 内存整理频繁回收对象之后内存中产生大量不连续的空间, 我们把这些不连续的空间成为内存碎片

    5.副垃圾回收器

    • 负责收集新生代区域产生的垃圾,大多数小对象会被分配搭配这个区域所以收集比较频繁
    • 新生代中使用Scavenge 算法
    • image.png
    • 新加入的对象会放入对象区域,当对象区域写满的时候就需要执行垃圾清理阶段
    • 会在对象区域中做垃圾标记,标记完之后副垃圾回收器就会把存活的对象复制到空闲区域中同时还会有序列的排列起来,这个复制过程完成了内存整理,复制后空闲区域就没有内存碎片了,对象区域与空闲区域发生了角色翻转,可以使这两个空间可以无限重复使用下去,因为比较频繁所以空间也不会太大
    • 对象晋升策略,经过两次垃圾回收的依然存活的对象会被移动到老生区中

    6.主垃圾回收器

    • 负责老生区的垃圾回收
    • 数据特点:对象占用空间大,对象存活时间长
    • 标记-清除(mark-sweep)算法,标记是从根元素开始遍历过程能到达的元素称为活动对象(有引用指向这个地址),没有达到的元素称为垃圾数据image.png
    • image.png
    • 标记清除之后会产生很多内存碎片还需要另一种算法标记整理(mark-compact)这个过程,不是清理可回收对象而是让存活对象向一端移动,然后清理掉端边界以外的内存
    • image.png

    7.全停顿

    • js是运行在主线程之上的,一旦执行垃圾回收算法,正在执行是js脚本就必须停止,回收完才可以恢复执行脚本
    • 增量标记算法:对于老生代垃圾回收,v8将标记过程分为一个个子过程与js应用逻辑交替进行,直到标记完成,对于新生代而言数据量少速度比较快影响不大image.png