V8引擎和内存管理

173 阅读4分钟

语言分类

解释型

  • 一边解释一边执行,特点是,启动快,执行慢。
  • php,MATLAB,Python,js等。
  • 解释型语言的执行效率比编译型慢。
  • 为了提高效率,通常会进行预编译

编译型

  • 先编译,再执行,特点是,启动慢,执行快。
  • 像C语言,C++。

V8引擎

  • v8引擎是用C++语言编写的,能够编译js代码的程序,编译后的js代码可以在多种操作系统多种处理器上运行。
  • 编译型和解释型相结合的方式,这种混合使用的方式称为JIT技术
  • V8负责编译和执行js代码,处理调用栈,内存分配,垃圾回收。
  • v8引擎的执行过程
    • 解析器解析js代码生成抽象语法树
    • 解释器根据抽象语法树生成字节码,同时清除抽象语法树
    • 解释器执行字节码,同时收集优化信息
    • 编译器根据字节码和信息来编译出优化的机器码

内存管理

基本类型数据存在栈内存,栈内存是操作系统分配的空间,自动分配,自动回收(函数调用完毕后就回收),引用数据类型存放在堆内存,但会这块空间的引用,堆内存是程序员操作的空间,由程序员回收。
手动管理内存:C、C++,包括早期的OC,都需要手动来管理内存的申请和释放的(malloc和free函数)。
自动管理内存:比如Java、Javascript、Python、Swift、Dart等。
我们创建的原始值、对象、函数等等一切都会占用内存,js引擎会自动帮我们管理这些内存。

内存的生命周期

  • 分配空间(申请)
  • 使用空间(存东西,如对象)
  • 释放空间

垃圾回收

v8引擎限制了内存的使用(64位约1.4G)。
需要垃圾回收的原因:

  • 原因:V8引擎是为浏览器设计的,不会遇到使用大量内存的场景,为了照顾到低内存的移动端设备,所以需要垃圾回收。

垃圾回收算法之引用计数法

在引用计数方法下,每个分配的对象都包含一个引用计数字段,每个对象的引用计数始终等于该对象的直接指针引用的数量,当创建或者删除某一对象的引用时增加或者减少该对象的引用计数,一旦引用数为0时,就被认定为垃圾,然后被回收。
引用计数法优点:

  • 发现了垃圾可以立即回收
  • 可以避免程序的暂停,因为一旦内存要饱满的时候,引用计数就会找到垃圾并进行回收。 引用计数法的缺点:
  • 无法回收循环引用的对象,比如两个对象互相引用。
  • 需要花时间维护引用数,一旦引用次数改变,引用数就要改变。

垃圾回收算法之标记清除算法

  • 标记清楚的核心思路是可达性。
  • 设置一个根对象,垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于那些没有引用到的对象,就认为是不可靠对象。
  • 这个算法可以解决循环引用的问题。

图片.png

垃圾回收算法的其他算法

标记整理:和标记清除类似,回收期间会将保留的存储对象汇集到连续的内存空间,从而整合空闲空间,避免碎片化。 分代收集:对象被分成两组,新生代的和旧生代的。

  • 一些变量创建完,很快就被使用然后被回收的对象,会被分到新生代空间里;
  • 那些长期存活的对象会从新生代空间里移到旧的空间里,被检查的频率会减少。 增量收集:
  • 一次性遍历所有标记对象是会需要大量时间的,带来明显延迟。
  • js引擎将垃圾收集工作分成几部分,将他们逐一处理,这样会有许多微小延迟而不是一个大延迟。 闲时收集:
  • 垃圾收集器只会在CPU空闲时尝试运行,以减少对代码执行的影响。

内存图:

图片.png