前端GC垃圾回收机制

news2025/1/18 4:43:47

js中的管理是自动的,对象不再被引用时就是垃圾,不能从根上访问时也是垃圾。

能够访问到的对象就是可达对象(引用,作用域链),可达的标准就是从根触发是否能够被找到,根可以理解为是全局变量。

GC是一种机制,垃圾回收,工作内容就是查找垃圾释放空间,回收空间。

常见GC算法:

  • 引用计算:给可达对象设置引用数,在引用关系发生改变时修改引用数字,判断当前引用数是否为0,如果是就回收。

        优点:发现垃圾时会立即回收,最大程度减少程序暂,

        缺点:无法回收循环引用的对象,要监控数据计算所需的时间比较久。

        这个就是循环引用的问题,函数释放时,obj1和obj2都应该被释放,但是却又被两者同时引用着,这个情况下就无法回收,造成资源了浪费。

function fn(){
    const obj1 = {}
    const obj2 = {}
    obj1.name = obj2
    obj2.name = obj1
    return '123'
}
fn()
  • 标记清除:分成两个阶段,遍历所有可达对象标记活动对象,然后遍历所有的对象清除没有标记的对象,回收相应的空间,在清除的阶段也会抹去之前的标记,以便下次工作。原理就是可以将可达对象的属性进行递归,间接可达对象每一项都会标记,在局部作用域的对象会被释放,所以不会被标记。

        优点:相对于引用计数,解决对象引用的循环引用回收,在函数作用于中的对象为不可达对象所以不会被标记,所以会直接释放。

        缺点:容易产生碎片化空间浪费空间。如下图,释放了三个字的空间,但是并不连续,中间还有个根对象,所以还是分散的,地址并不连续,所以后续如果需要1.5空间,那么左边的就多了0.5,右边的又不够,形成了空间的碎片化。

  • 标记整理:可以看做是标记清除的增强版本,标记阶段和标记清除一致,但是在清除阶段会先执行整理,移动对象的位置,然后清理。

V8引擎回收策略

        V8引擎是一款主流的js执行引擎,很多引擎需要将代码转为字节码,然后执行,V8可以即时编译,V8内存设有上限,在64位操作系统上限是1.5G,对于32位的不超过800M,原因:V8就是为了浏览器而制造的,所以现有的内存大小对于网页应用来说是足够使用,再者 V8内部所需实现垃圾回收的机制也决定了采用这个机制是十分合理的。

V8垃圾回收采用分带回收的思想,对于新生代和老生代使用不同的方法:

 分带回收 空间复制 标记清除 标记整理 标记增量

V8分配内存:

内存空间一分为二

小空间用于存储新生代对象(32M|16M)对应64和32位的系统

新生代对象指存活时间较短的对象,比如局部作用域的变量。

 新生代

复制算法+标记整理:新生代的内存又分为两个等大小的空间,使用f空间为From,空闲空间为To,活动对象存储于From空间,当From空间使用到一定程度时候,就要触发GC操作,所以此时会使用标记的操作对From空间进行活动对象的标记,找到活动对象之后,使用整理的操作让位置变得连续,避免碎片化空间,之后会复制这样的活动对象到To空间,也就是From空间的活动对象都有了备份,这时候考虑做回收操作,释放From空间,因为To空间对From的活动对象已经有所体现,所以可以回收释放From空间,类似于From空间和To空间进行了交换转变,就完成了新生代对象的回收。

在复制过程中如果发现某一个变量所启用的空间在当前的老生代对象中也会出现,这时就会出现晋升的操作,指将新生代的对象移动到老生代进行存储,什么时候触发晋升呢?

两个判断标准:

  1. 如果新生代中某些对象经过一轮GC之后还活着,这个时候就可以拷贝到老生代进行存储。
  2. 在拷贝的过程中,发现To空间的使用率超过了25%,那么也需要将活动对象移动到老生代进行存储。之所以定一个上限也是因为在To转变为From后,变为使用状态,新的活动对象也会存储进来,但是超过80%就存不进去了。

老生代

大空间用于存储新生代对象(1.4GM|700M)对应64和32位的系统。

老生代对象其实就是指存活时间较长的对象,比如全局变量,闭包等。

主要采用标记清除,标记整理,增量标记算法。

首先使用标记清除完成垃圾的空间回收。显而易见,会出现空间碎片化的问题,相比于空间碎片,但是提升的速度会很大,所以V8引擎还是会采用标记清理。当新生代有对象要在老生代对象进行存储时,并且老生代的空间不足以存储,也就是在晋升的情况下,会触发标记整理,会将之前的一些空间碎片进行回收,就能有更多的空间使用。

新生代垃圾回收使用空间换时间,使用复制算法,每时每刻都会有一个空闲的空间存在,由于新生代的存储空间本来就小,分出来后会更小,这一部分的空间浪费比起时间上的提升还是微不足道的。

老生代存储空间很大,不适合复制算法,而且数据很多。

老生代标记增量怎么理解呢? 

当垃圾回收时,会阻塞js的执行,将一整段的垃圾回收拆分成许多小步,组合交替完成垃圾回收,替代之前一口气完成的垃圾回收,会降低时间消耗,第一次标记号所有直接可达对象,然后执行js代码,再进行间接可达对象的标记,以此类推,最后清除。

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

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

相关文章

【机器学习】 - 作业7: 某闯关类手游用户流失预测

课程链接: 清华大学驭风计划 代码仓库:Victor94-king/MachineLearning: MachineLearning basic introduction (github.com) 驭风计划是由清华大学老师教授的,其分为四门课,包括: 机器学习(张敏教授) , 深度学习(胡晓林教授), 计算…

并发和线程

并行和并发 1.并行跟并发有什么区别? 从操作系统的角度来看,线程是CPU分配的最小单位。 并行就是同一时刻,两个线程都在执行。这就要求有两个CPU去分别执行两个线程。 并发就是同一时刻,只有一个执行,但是一个时间段…

详解HTTPS加密过程

目录 前言 HTTPS是什么 HTTPS的工作过程 引入对称加密 引入非对称加密 引入证书 总结 前言 对于HTTP上篇文章已经做了详细的解释了。众所周知,HTTPS要比HTTP要安全,但是为什么HTTPS要比HTTP安全呢? 这篇文章主要研究HTTPS的加密机制…

操作系统-X18 linux日志审计

Linux日志审计 在unix/类unix(Linux)系统中,日志是内核(内存)的一部分。 用于记录系统、程序运行中发生的各种事件 通过阅读日志,有助于诊断和解决系统故障 日志文件的分类 ①内核及系统日志 由系统sysl…

队列及其实现

目录 一&#xff1a;队列 1.队列的概念及结构 2.队列的实现 <1>.初始化队列 <2>.队尾入队列 <3>.队头出队列 <4>.获取队列头部元素 <5>.获取队列队尾元素 <6>.获取队列中有效元素个数 <7>.销毁队列 二&#xff1a;完整代…

如何完全卸载IDEA

工欲善其事必先利其器&#xff0c;我们在用idea的时候&#xff0c;idea的环境出现了莫名其妙的问题&#xff0c;怎么也找不到问题原因。有时候也可能是安装了不知名VB脚本&#xff0c;给系统装了一大堆的环境变量(如下图所示)&#xff0c;这个时候你可以试着把idea卸载重新安装…

Jetpack Compose UI预览

Android开发 Jetpack_Compose_2 UI预览Preview 前言 在学习jetpack compose如何编写ui之前&#xff0c;我认为还是应该先了解与Android studio配合的UI预览Preview。 这样就可以立刻看到UI效果&#xff0c;从而方便后续学习验证代码。 所需依赖 implementation "androidx…

CAPL(vTESTStudio) - 自动创建带有时间戳的报告和log

目录 getLocalTime - 获取本地时间函数 代码示例 获取当前时间并形成格式:"2023_05_22_23_20_18"

Qt中的坐标系

Qt中的坐标系 Qt中的坐标系与win10上画图工具的联系 上面这个图片的水印挡住了重要信息,然后又截了一张,显然,画图工具的像素就是Qt中的坐标系,所以,以后查坐标系直接打开Qt:画笔位置所显示的像素就是Qt的坐标!!! 再总结一下: 好奇:win10上的画图工具是qt写的吗? 答: 不是…

【SpringCloud】Nacos

文章目录 一、Nacos1、安装2、服务注册和发现3、服务分级存储模型4、负载均衡策略--NacosRule5、服务实例的权重设置 一、Nacos 1、安装 官网&#xff1a;https://nacos.io/zh-cn/ 下载 Github主页: https://github.com/alibaba/nacos Github的Release下载页: https://githu…

linux命令行如何查看命令帮助信息

一&#xff0c;简介 “授之以鱼不如授之以渔”&#xff0c;我们再学习linux命令的时候&#xff0c;想查看某个命令的详细说明&#xff0c;有哪些方法呢&#xff1f;本文来介绍一下如何在命令行查找命令的帮助信息。 二&#xff0c;linux命令格式介绍 Linux命令一般由三部分组…

【深度学习】- 作业1: Softmax实现手写数字识别

课程链接: 清华大学驭风计划 代码仓库&#xff1a;Victor94-king/MachineLearning: MachineLearning basic introduction (github.com) 驭风计划是由清华大学老师教授的&#xff0c;其分为四门课&#xff0c;包括: 机器学习(张敏教授) &#xff0c; 深度学习(胡晓林教授), 计算…

【深度学习】 - 作业7: 图像超分辨率重建

课程链接: 清华大学驭风计划 代码仓库&#xff1a;Victor94-king/MachineLearning: MachineLearning basic introduction (github.com) 驭风计划是由清华大学老师教授的&#xff0c;其分为四门课&#xff0c;包括: 机器学习(张敏教授) &#xff0c; 深度学习(胡晓林教授), 计算…

Linux网络编程—Day10

Linux服务器程序规范 Linux服务器程序一般以后台进程形式运行。后台进程又称守护进程。它没有控制终端&#xff0c;因而也不会意外接收到用户输入。 守护进程的父进程通常是init进程&#xff08;PID为1的进程&#xff09;&#xff1b;Linux服务器程序通常有一套日志系统&#…

Android 11.0 系统设置显示主菜单添加屏幕旋转菜单实现旋转屏幕功能

1.前言 在android11.0的系统rom定制化开发中,在对系统设置进行定制开发中,有产品需求要求增加 旋转屏幕功能的菜单,就是在点击旋转屏幕菜单后弹窗显示旋转0度,旋转 90度,旋转180度, 旋转270度针对不同分辨率的无重力感应的大屏设备的屏幕旋转功能的实现, 接下来就来分析…

chatgpt赋能Python-python_dill

Python dill - 更高效&#xff0c;更强大的对象序列化工具 在Python编程中&#xff0c;对象序列化是一个非常常见的操作&#xff0c;它将Python对象转换为可以存储或传输的格式。Python默认提供了pickle模块来实现序列化&#xff0c;但是pickle存在一些限制&#xff0c;比如无…

usb摄像头驱动-core层usb设备的注册

usb摄像头驱动-core层driver.c 文章目录 usb摄像头驱动-core层driver.cusb_bus_typeusb_device_matchusb_uevent usb_register_driver 在ubuntu中接入罗技c920摄像头打印的信息如下&#xff1a; 在内核中&#xff0c;/driver/usb/core/driver.c 文件扮演了 USB 核心驱动程序管…

复现ms17-010漏洞

复现ms17-010 复现条件环境操作效果 让我们来看看“hkl”在干嘛 复现 条件 1.靶机必须为win8以下。 2.靶机必须同攻击机处于相同网段&#xff08;即倒数第二位相同&#xff09;。 3.靶机的445端口必须要开启。 环境 虚拟机kali为攻击机&#xff0c;win7虚拟机为靶机。 kali…

SELECT LAST_INSERT_ID()自增主键冲突或者为0问题

问题 数据库为mysql&#xff1b; mapper.xml文件为mybatis-generator自动生成的&#xff1b; 连接池使用DruidDataSource&#xff1b; 最终生成的insertSelective如下&#xff1a; 出现问题&#xff1a; 主键冲突&#xff1a;[WMyBatisTraceInterceptor:54][com.mysql.jdbc.…

如何定位OOM

造成OOM的原因 定位OOM 针对第一和第二种情况需要定位OOM 系统已经挂了&#xff1a; 通过堆dump文件定位。 当JVM发生OOM时&#xff0c;自动生成DUMP文件&#xff1a; -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath${目录} java -Xms10M -Xmx10M -XX:HeapDumpOnOutOfMemo…