前端知识点-内存篇

225 阅读4分钟

内存

内存用于暂时存放CPU中的运算数据,与硬盘等外部存储器交换的数据。是外存与CPU进行沟通的桥梁

V8

  1. V8 是一款主流的JavaScript执行引擎

  2. 采用即时编译(转为机器码),其它引擎提前转为机器吗后在执行

  3. V8垃圾回收策略

    1. 分代回收
    2. 空间复制
    3. 标记清除
    4. 标记整理
    5. 标记增量

内存管理

  • 内存:由可读写单元组成,表示一片可操作空间,我们平常创建基本类型,对象,数组等都需要内存。既然有使用就会有管理。js中的内存管理分为三步:1. 申请内存空间, 2. 使用内存空间,3. 释放内存空间。

    在 js 中,不能像c和c++ 主动调用api 来管理

    let obj = {} 赋值 自动会分配一块内存

    obj.name="lg" 使用空间

    obj = null; 释放内存

可达对象

  • 可以访问到的对象就是可达对象 (引用,作用域链)

  • 可达的标准就是从根出发是否能够被找到

  • js 中全局变量对象就是根 (全局上下文)

垃圾回收 简书

  • js 中内存管理是自动的

  • 对象不再被引用的时候是垃圾 (通过引用关系无法找到某些对象的时候)

  • 对象不能被正确访问的时候 (对象存在,因语法错误或结构错误无法找到的对象)

  • GC(垃圾回收) 算法

    • 找到内存中的垃圾,并释放和回收空间

      • 在运行中,上下文中不再需要时
      • 在代码中,外部环境找不到对象时
    • 常见GC算法

      • 引用计数

        • 给每个对象添加一个引用计数器,标识对象的引用次数,当一个新引用指向对象时计数器加1,当指向对象的引用失效时计数器减1,当计数器为0时会被立即回收

        • 优点:

          1. 立即回收
          2. 最大限度减少程序暂停
        • 缺点:

          1. 无法回收循环引用的对象
            function fn() {
              const obj1 = {}
              const obj2 = {}
              //全局作用域下找不到obj1,obj2,但是obj1.name,obj2.name还引用着,所以引用数不为0
              obj1.name = obj2;
              obj2.name = obj1
              return 'xxxx'
          }
          fn()
          
          1. 时间开销大(维护数值变化(监听),对象修改,引用计数也需修改)
      • 标记清除

        • 分标记和清除两个阶段完成

        • 遍历所有对象找标记活动对象

          • 标记计数时会递归的查找引用层级关系,把可达对象进行标记
        • 遍历所有对象清除没有标记对象

          1. 清除没有标记的对象

          2. 标记清除将回收的空间放在空闲列表上面,方便后面的程序直接在这里申请内存使用。

        • 回收相应空间

        • 优点

          1. 解决对象循环引用不能回收的问题(相对于引用计数)
        • 缺点

          1. 空间碎片化(由于回收的空间地址不连续),不能是空间最大化使用
          2. 不会立即清除垃圾
      • 标记整理

        • 标记整理算法是标记清除算法的一个升级。主要是为了减少碎片空间化。工作原理与标记清除算法相同。
        • 相比于标记清除,在清除没有标记的对象之前,把这些垃圾对象移动位置,也就是先进行整理到一块后再清理,这样减少了碎片化空间
      • 分代回收

        • 内存设限:64位内存不超过1.5G,32位不超过800m

        • 内存空间分为 新生代(存活时间短)和老生代

          • 小空间用于存储新生代对象(32m[64位] | 16m[32位])

          • 新生代对象回收

            • 回收过程采用复制算法+标记整理

            • 新生代内存区分为二个等大小空间

            • 使用空间位From,空闲空间位To

            • 活动对象存储于From空间

            • 标记整理后将活动对象拷贝至To

            • From 与 To交换空间完成释放

              ​ 回收细节

              1. 拷贝过程中可能出现晋升
              2. 晋升就是将新生代对象移动至老生代
              3. 一轮GC还存活的新生代需要晋升
              4. To空间的使用率超过25%
          • 老年代对象 (1.4G[64位] | 700m[32位])

            • 老年代对象就是存活时间长的对象
            • 主要采用标记清楚,标记整理,增量标记算法
            • 首先(主要)使用标记清除完成垃圾空间的回收
            • 采用标记整理进行空间优化
            • 采用增量标记来进行效率优化