浏览器工作原理学习(十一)

news/2024/7/3 19:48:18

语言类型

  • 在使用前需要确认其变量数据类型的称为静态语言©,运行过程中需要检查数据类型的语言称为动态语言(js)。
  • 在赋值时,语言回进程隐式类型转换,这类语言被称为弱类型语言,不支持隐式类型转换额语言称为强类型语言。
  1. JS数据类型
  • JS是一种弱类型的、动态的语言:弱类型即不需要声明变量类型JS引擎在运行代码的时候会自己计算出来,动态即可以使用一个变量保存不同类型的数据。
  • 原始类型:Boolean、Null、Undefined、Number、Sybmol、String、BigInt。
  • 引用类型:Object。
  1. JS内存空间
  • JS执行过程中主要有三种类型内存空间,分别是代码空间、栈空间和堆空间。
  • 栈空间:调用栈空间,用来存储执行上下文的。
  • 堆空间:js引擎判断出变量类型为引用类型,这个时候JS引擎不是直接将该对象放到变量环境中,二十将它分配到堆空间,分配后该对象会有一个在堆中的地址,然后在将该数据的地址写进引用变量的变量值中。
  • 不将数据都放入栈空间是因为JS引擎需要栈来维护程序执行期间上下文的状态,提高上下文切换的效率,从而提高整个程序的执行效率。
  • JS原始类型的数据值直接保存在栈中,引用类型的值保存在堆中。
  • 堆空间很大,能存放很多大的数据,不过缺点是分配内存和回收内存都会占用一定的时间。
  1. 闭包
  • 闭包产的核心有2部:第一步是需要预扫描内部函数;第二步是把内部函数引用的外部变量保存在堆中。

垃圾回收机制

  • 数据被使用之后,之后不再需要了被称为垃圾数据。如果垃圾数据一直保存在内存中,那么内存会越用越多,所以堆垃圾数据进行回收,可以释放游下的内存数据空间。
  • 不用语言的垃圾回收策略各不相同,通常氛围手动回收和自动回收。
  • C/C++采用的是手动回收策略:何时分配内存、何时销毁内存都由代码控制,可以调用mallco函数来分配内存,free函数来释放内存,然后分配内存后,当数据不需要时,代码没有主动调用free函数来销毁,这种情况被称为内存泄漏。
  • 自动回收策略:产生的垃圾数据是由垃圾回收其来释放的。
  1. JS调用栈中的数据是如何回收的?
  • 调用栈中记录当前执行状态的指针(称为ESP),指针下移操作就是销毁对应函数执行上下文的过程。同时该函数在调用栈中为无效内存,下一个入栈的函数会覆盖掉改块内存空间。
  1. JS堆中的数据是如何回收的?
  • 要回收堆中的垃圾数据,就需要用到JS中的垃圾回收器了。
  • 代际假说:特点一对象已经分配内存,很快就变得不可访问,特点二:不死的对象,会活的很久。这2特点适合大多数的动态语言。
  • V8会把堆分为新生代和老生代两个区域,新生代存放的是生存时间短的对象,老生代中存放的生存时间久的对象。
  • 新生区:通常只支持1-8M容量,使用副垃圾回收器回收垃圾数据。
  • 老生区:存放得容量较大,使用主垃圾回收器回收垃圾数据。
  1. 垃圾回收器的工作流程
  • 标记空间中活动对象和非活动对象。所谓活动对象就是在使用对象,非活动对象就是可以进行垃圾回收的对象。
  • 回收非活动对象所占据的内存。在所有的标记完成后,统一清理内存中被标记为可回收的对象。
  • 内存整理:频繁回收对象后,内存中会存在大量不连续空间,我们把这些不连续的内存空间称为内存碎片,当内存中出现大量的内存碎片后,如果需要分配较大连续内存的时候肯出现内存不足的情况。
  1. 副垃圾回收器
  • 采用Scanvenge算法:把新生代空间对半划分为2个区域,一半是对象区域,一半是空闲区域,
  • 新加入的对象会存放在对象区域,当对象区域快被写满时,就需要执行一次垃圾清理操作。
  • 垃圾清理过程中,首先需要对对象区域中的垃圾做标记,标记完成后,就叫你如垃圾清理阶段。
  • 副垃圾回收器会把这些才能活的对象复制到空闲区域,同时它还会把这些对象有序地排列起来,这个过程久称为内存整理操作,复制后空闲区域就没有内存碎片了。
  • 完成复制后,对象区域和空闲区域进行角色反转,这样就完成了垃圾对象的回收操作了,同时这种角色翻转的操作还能让新生代中的这2块区域无限重复使用下去。
  • 复制操作需要时间成本,为了执行效率,一般新生区的空间会被设置的比较小,所以很容易被存活的对象装满整个新生区域。为此JS引擎采用对象晋升策略,经过2此垃圾回收依然还存活的对象,会被移动到老生区中。
  1. 主垃圾回收器
  • 除了新生区中晋升的对象,一些大的对象会直接分配到老生区,因此老生区有2个特点,对象占用空间大,对象存活时间长。
  • 采用标记-清除(Mark-Sweep)的算法进行垃圾回收。
  • 首先标记过程阶段:从一组根元素开始,递归遍历这组根元素,在这个遍历过程中,能到达的元素称为活动对象,没有到达的元素可以判断为垃圾数据。
  • 垃圾清除过程:这一过程会参数大量不连续的内存碎片,当碎片过多会导致大对象无法分配到足够的连续的内存,为此产生了另一种算法"标记-整理(Mark-Compact)",后续不走不是直接对可回收的对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉边界以外的内存。
  1. 全停顿
  • JS时运行在主线程之上的,一旦执行垃圾回收算法,都需要将正在执行的JS脚本暂停下来,待垃圾回收完毕后在恢复脚本执行,这种行为被称为全停顿。
  • 为了降低老生代的垃圾回收而造成的卡顿,V8将标记过程氛围一个个的子标记过程同时让垃圾回收标记和JS应用逻辑交替进行,直到标记阶段完成,这个算法被称为”增量标记(Incremental Marking)“算法。

http://www.niftyadmin.cn/n/2608625.html

相关文章

【跃迁之路】【423天】刻意练习系列182—SQL(2018.04.04)

(跃迁之路)专栏 叨叨两句 技术的精进不能只是简单的刷题,而应该是不断的“刻意”练习该系列改版后正式纳入【跃迁之路】专栏,持续更新刻意练习——MySQL 2018.04.02 题目描述 DROP TABLE IF EXISTS test1;CREATE TABLE test1 (id int(11) NOT NULL AUTO_…

浏览器工作原理学习(十二)

编译器和解释器 按语言的执行流程,可以把语言划分为编译型语言和解释型语言。编译型语言:在程序执行前,需要经过编译器的编译过程,并且编译之后会直接保留机器能读懂的二进制文件,这样每次运行程序时,都可以…

离线计算成本节省的神兵利器

摘要: 对于创业成长型的企业来说,离线计算已经必不可少了,通过离线计算我们可以生成复杂的业务报表,通过离线计算我们也能精确的算出用户画像。离线计算已经当今的企业中成为了不可或缺的存在。那么使用弹性计算能够对离线计算领域…

浏览器工作原理学习(十三)

消息队列和事件循环系统 消息队列 消息队列是一种数据结构,可以存放要执行的任务。它符合队列先进先出的特点。IO线程中的产生的新任务会添加进消息队列尾部。渲染主线程会循环地从消息队列头部中读取任务,执行任务。由于多个线程操作同一个消息队列&am…

浏览器工作原理学习(十四)

WebAPI:setTimeout 浏览器中的setTimeout 执行一段异步任务,需要先将任务添加到消息队列中。为了保证回调函数能在指定时间内执行,定时任务的回调函数不能直接添加到消息队列。延迟队列:维护消息队列中需要延迟执行的任务列表。如果当前任务…

(牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)

假定一种编码的编码范围是a ~ y的25个字母,从1位到4位的编码,如果我们把该编码按字典序排序,形成一个数组如下: a, aa, aaa,aaaa, aaab, aaac, … …, b, ba, baa, baaa, baab, baac … …, yyyw, yyyx,yyyy 其中a的Index为0&…

浏览器工作原理学习(十五)

微任务与宏任务 宏任务 为了协调任务在主线程上执行,页面进程引入消息队列和事件循环机制,渲染进程内部会维护多个消息队列,主线程从这些任务队列中取出任务执行,这写消息队列种的任务称为宏任务。 微任务 第一种:把…

django markdown

1. 编辑器 css 1 <link rel"stylesheet" href"{% static plugin/editor.md/css/editormd.css %}"> div 1 <div id"editormd" class"col-md-10 text-left"> 2 <textarea name&…