v8垃圾回收

news2025/1/12 4:05:07

文章目录

  • 内存的生命周期
  • v8垃圾回收算法
    • 新生代
      • Scavenge
      • 图例
    • 老生代
      • Mark-Sweep
      • Mark-Compact
      • 图例
    • v8垃圾回收的弊端
    • v8垃圾回收优化

内存的生命周期

内存的生命周期可以分为三个阶段:

  • 内存分配:按需分配内存
  • 内存食用:读写已经分配的内存
  • 内存释放:释放不再需要的内存
    在js当中内存的分配是根据变量的数据类型进行分配的:
  • 栈内存:是一种简单储存,适合存放生命周期比较短,占用空间较少而且固定的数据,由系统直接管理,进行内存的分配和自动释放。一般都是基本数据类型分配在栈内存当中。(基本数据类型有Number;Boolen;String;Null;Undefined;Symbol)
  • 堆内存:是很大的一个存储空间。堆内存按需进行内存空间的申请,动态分配且不连续,值大小不固定,访问速度比栈内存要慢,无用数据需要JS引擎程序主动去回收。一般都是引用数据类型的值放在里面

注意:引用类型的数据会同时分配在栈内存和堆内存,其地址存在栈内存,其具体内容存在堆内存中(这个也是基本数据类型和引用数据类型的区别)

特殊:全局变量(使用var声明)和闭包都是存储在堆内存当中

v8垃圾回收算法

在js当中,根据对象的存活的周期分为两种类型:

  • 生存时间较短:对象经过一次垃圾回收之后不在被使用,就被释放回收
  • 生存时间较长:对象经过多次垃圾回收之后还是继续存活。

对于不同的生存时间,v8使用分代回收的方法来处理。v8将堆划分为两个部分:新生代和老生代

区域垃圾回收器
新生代副垃圾回收器
老生代主垃圾回收器

新生代

副垃圾回收器主要使用Scavenge算法进行垃圾回收,Scavenge算法是一种典型的使用空间换时间的算法,它将新生代空间的堆内存分为2块同样大小的空间,称为Semispace,我们将处于使用状态的区域叫作From空间,闲置的区域叫作To空间

Scavenge

Scavenge算法在每次执行清理操作时,都需要将存活的对象从对象区域复制到空闲区域。但复制操作需要时间成本,如果新生区空间设置得太大了,那么每次清理的时间就会过久,所以为了执行效率,一般新生区的空间会被设置得比较小。
Scavenge算法工作方式是将From空间中存活的活动对象复制到To空间中,并将这些对象的内存有序的排列起来,然后将From空间中的非活动对象的内存进行释放,完成之后,将From空间和To空间进行互换,这样可以使得新生代中的这两块区域可以重复利用。

图例

  1. 标记活动对象和非活动对象(红色肥活动,绿色活动)

在这里插入图片描述

  1. 复制From空间的激活对象到To空间并进行排序

在这里插入图片描述

  1. 清除From空间中未激活的对象
    在这里插入图片描述
  2. 互换From和To空间
    在这里插入图片描述
  3. 循环以上步骤

注意:在新生代中,还进行了进一步的细分,分为nurdery 子代和intermediate子代连哥哥区域,一个对象第一次分配内存的时候会被分到nurdery中,如果进行下次垃圾回收的时候这个对象还存在于新生代当中,这时候会将它移动到intermediate中,再进行下一次垃圾回收,如果这个对象还在新生代中,副垃圾回收器会将该对象移动到老生代中,这个移动的过程被称为晋升

老生代

老生代由于存活时间比较 长,如果按照新生代的scavenge算法进行回收时,From与To之间循环会造成严重的空间资源浪费,效率低下,所以,针对老生代,主垃圾回收器采用了Mark-Sweep(垃圾扫除)算法和Mark-Compact(垃圾整理)算法进行垃圾回收

Mark-Sweep

首先是标记阶段,将堆中的所有对象进行递归(包括调用栈),在遍历的过程,标记激活对象和未激活对象,标记完成后就会进行清除。清除是将不可访问的对象留下的内存空间添加到空闲链表。目的是将来如果要给新对象分配内存时,就可以直接从空闲链表中进行分配。

Mark-Compact

由于Mark-Sweep算法,产生了许许多多的内存碎片。如果内存碎片过多的画会导致大的激活对象没有办法分配到相应的连续内存,所以,为了减少并整理内存碎片,就需要Mark-Compact来进行整理。
首先就是标记过程,将堆中的所有对象进行递归(包括调用栈),在遍历的过程,标记激活对象和未激活对象,然后将所有激活对象移到一端,然后清理边界以外的内存,从而让激活对象占用连续的内存。

图例

  1. 标记激活对象和未激活对象
    在这里插入图片描述

  2. 清除未激活对象
    在这里插入图片描述

  3. 将激活对象移动到一端
    在这里插入图片描述

  4. 清理边界以外的内存

v8垃圾回收的弊端

js是运行在主线程之上的,为了避免js的应用逻辑和垃圾回收产生冲突,垃圾回收正在执行的时候会占用js引擎,正在执行的js脚本就会暂停,等到垃圾回收结束后js脚本才会继续执行,这个过程称为全停顿
在v8的分代式垃圾回收中,新生代默认的内存较小,所以大部分都是分到老生代,由此垃圾的标记,清理造成的停顿就会比较严重。

v8垃圾回收优化

为了优化停顿带来的影响,v8中加入了其他的垃圾回收技术:

  • 标记阶段

增量标记:在老生代中,存活对象较多,较大,全停顿造成的页面卡顿或者空白较多较长,产生的影响比较大,为了减少全停顿的时间,v8对标记进行了优化,当垃圾达到一定的数量的时候,将一次停顿进行的标记过程分成了各个小步。每执行一小步就运行一点js逻辑代码,然后交替完成标记,减少每次停顿的时间。(有点像是减少时间,增加次数)
在这里插入图片描述

  • 清理阶段

延迟清除:在增量标记之后就要对非激活对象进行清除。但是其实就算这个阶段不清理,垃圾回收器剩余的内存也能让js逻辑代码跑起来,所以就有了来进行延迟清理或者之清理部分垃圾的算法—延迟清除。
写屏障
虽然在标记阶段增加了增量标记改善了全停顿的问题,但是也引发了一个新的问题:标记和代码之间的穿插可能会让对象的引用和标记发生错误。应用程序必须通知垃圾收集器关于改变对象的所有操作。由此v8采用Dijkstra风格的写屏障来实现通知。例如object.field=value的写操作之后,V8会插入写屏障代码。写屏障机制强制不变黑的对象指向白色对象。这也被称为强三色不变性,保证应用程序不能在垃圾收集器中隐藏活动对象,因此标记结束时的所有白色对象对于应用程序来说都是不可达的,可以安全释放。
并行
并行是指主线程和辅助线程同时执行大致相等的工作量,这也是解决全停顿的方法。与延迟清除不一样的是总的停顿时间是因为辅助线程的参与而得到减少,由于辅助线程没有运行js,所以每个辅助线程只需要确保同步GC就可以。
在这里插入图片描述
参考文献

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/94577.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 管理联网 配置网络的四种方法 配置临时连接( ip 命令)

配置网络 # 网络接口是指网络中的计算机或网络设备与其他设备实现通讯的进出口。这里,主要是 指计算机的网络接口即 网卡设备 # 网络接口 -- 网卡 的命名 : 从RHEL7开始引入了一种新的“一致网络设备命名”的方式为网络接口命名,该…

【Java笔记】 深入理解序列化和反序列化

深入理解序列化和反序列化 文章目录深入理解序列化和反序列化1.是什么2.为什么3.怎么做3.1 实现Serializable接口3.2 实现Externalizable接口3.3 注意知识点3.4 serialVersionUID的作用4 扩展1.是什么 序列化:就是讲对象转化成字节序列的过程。 反序列化&#xff…

C++开发,这些GUI库一定不要错过

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 如果问Python这类集成度非常高的编程语言GUI开发用什么库,可以列举出很多不错的第三方库。 但是,如果这个问题放在C这种基础的编程语言上,很多同学估计一时间都无从…

用Gurobi+python求解设施选址问题(facility location)

参考:Gurobi 官方资源 设施选址(Facility Location) 1.背景介绍 设施选址问题在许多工业领域如物流,通信等都有应用,在本案例中展示如何解决设施选址问题,决策出仓库的数量和地点,为一些超市…

Crash Consistency on File Systems: 文件系统一致性保证 (1) Journaling File System

文件系统是操作系统中管理用户数据的重要模块。其中一项重要的任务就是确保用户数据的在系统突然崩溃之后,系统能够恢复出完整、一致的用户数据。本文将会分析两种流行的文件系统,Journaling File System 和 Log-structured File System是如何确保数据的…

dataFactory连接mysql详细配置教程

场景:最近项目提出机构用户中其中一个部门下用户人数有20万,加载的时候十分缓慢,本地想重现的一下,这就需要在本地表中生成>20万的数据,搜索了网上的教程写的都是很粗略。 目录 dataFactory连接mysql配置 安装包下…

第二证券|“20cm”涨停!盘中暴涨110%,又有港股暴力拉升

A股商场今日上午窄幅动摇,电子等板块领涨。北向资金半响净买入额到达26.10亿元。 港股商场今日上午动摇也较为温和。不过,仍有个股剧烈动摇。比如浦江世界上午暴升,盘中涨幅一度超过110%。 A股窄幅动摇 电子板块领涨 今日上午A股商场全体体…

STL六大组件之算法

文章目录56、STL六大组件之遍历算法57、STL六大组件之查找算法158、STL六大组件之查找算法259、STL六大组件之统计算法60、STL六大组件之合并算法61、随机数(rand)和随机数种子(srand)的理解62、STL六大组件之随机算法(洗牌算法)6…

javaweb笔记

javaweb数据库jdbcmaven数据库 1.chart定长 2.分组查询:where>聚合函数>having 3.分页查询: select 字段列表 from limit 起始索引, 查询条目数 计算公式: 起始索引(当前页码-1)每页显示的条数 不同数据库分页查询不一样 4.like模糊查…

8种常见python运行错误,看看你中招了没?

人生苦短 我用python 对于刚入门Python的新手同学来说, 在运行代码时总免不了报错。 如何通过报错查找错误代码? 今天给大家总结了一些常见的报错类型, 每种报错都会有标有错误细节和错误行。 大家以后看到了,就更容易找出自…

使用navicat工具生成表的新增字段sql

1、在需要的表右键,设计表 2、点击【添加字段】 3、创建字段及注释,不要点【保存】和CtrlS 4、点击【SQL预览】 5、复制生成的sql语句

iframe 标签

一. 什么是 iframe 1. iframe 是 HTML元素,用于在网页中内嵌另外一个网页. 2. iframe 默认有一个宽高,存在边界. 3. iframe 是一个行内块级元素,可以通过 display 修改. 二. iframe 元素属性 1. src : 指定内联网页的地址 2. frameborder : iframe 默认有个边界,可以设置fram…

深入剖析Linux RCU原理(一)初窥门径

说明: Kernel版本:4.14ARM64处理器,Contex-A53,双核使用工具:Source Insight 3.5, Visio 1. 概述 RCU, Read-Copy-Update,是Linux内核中的一种同步机制。RCU常被描述为读写锁的替代品&#xf…

Openssl 1024bit RSA算法---公私钥获取和处理(一)

1.简介 使用OpenSSL生成公私钥文件,然后再将文件中的信息读出的操作。 由于要对设备升级,需要用到RSA算法对一部分验证信息进行加密. 2.使用OpenSSL获取公私钥 我在window系统尝试安装OpenSSL,但是安装不上,我们可以使用linux…

模式识别 第7、8章 特征的选择和提取

基本概念 问题的提出 特征→ 特征空间: 每一个特征对应特征空间的一个维度 ;特征越多,特征空间的维度越高原则:在保证分类效果的前提下用尽量少的特征来完成分类基本概念 (1)特征形成:由仪器…

如何去除图片雾化?给你推荐图片去雾怎么去除的方法

小伙伴们会不会和我一样喜欢外出爬山呢?为了留住美好记忆,我们会在途中拍照记录。但是山上很经常会有雾气,会容易导致我们拍出来的图片模糊不清。那应该怎么办呢?其实,我们只要对图片进行去雾处理就可以很好解决这个问…

[附源码]Nodejs计算机毕业设计基于的校园疫情防控管理Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置: Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分…

Web(十一)JavaScript知识训练-数学对象

1、Math.ceil(-3.14)的结果是( B)。 A、 -3.14 B、 -3 C、 -4 D、 3.14 2、Math.floor(-3.14)的结果是( C)。 A、 -3.14 B、 -3 C、 -4 D、 3.14 3、Math.round(-3.14)的结果是( B)。 A、 -3.14 B、 -3 C…

Spring Cloud Openfeign微服务接口调用与Hystrix集成实战

关于openfeign 可以认为OpenFeign是Feign的增强版,不同的是OpenFeign支持Spring MVC注解。OpenFeign和Feign底层都内置了Ribbon负载均衡组件,在导入OpenFeign依赖后无需专门导入Ribbon依赖,用做客户端负载均衡,去调用注册中心服务…

dataFactory向mysql批量插入测试数据

目录 第一步:准备阶段:datafactory已连接app_user的表 第二步: 点击原表app_user,其中属性界面properties中配置含义如下: 第三步:根据需要设置插入字段 第四步:设置每个字段的规则后,点击se…