首页 > 编程知识 正文

浏览器输入地址后发生的全过程,荣耀v8浏览器

时间:2023-05-06 00:52:20 阅读:175584 作者:1358

1、进程和线程进程和线程是操作系统的基本概念。

进程:

进程是具有一定独立功能的程序在一个数据集上动态运行的进程,操作系统是进行资源分配和调度的独立单位,是APP应用执行的载体。 这里把过程比作工厂的工厂。 它表示CPU可以处理的各个任务。 在任一时刻,CPU始终运行一个进程,而其他进程处于非运行状态。

线程:

早期的操作系统没有线程概念,进程是拥有资源且能够独立执行的最小单位,也是程序执行的最小单位。 任务调度采用的是时间片轮转方法,每个时间片都有独立的内存块,以便进程和进程之间的内存地址是任务调度的最小单元。 此后,随着计算机的发展,对CPU的要求越来越高,进程间切换的开销变大,已经不能适应越来越复杂的程序要求。 于是线程被发明了。 线程是程序执行中的单个顺序控制过程,是程序执行流的最小单位。 这里把线程比作一个车间的工人。 这意味着,在一个车间里,多名工人可以合作完成一项任务。

进程和线程的区别和关系:

进程是操作系统分配资源的最小单位,线程是程序执行的最小单位。 进程由一个或多个线程组成,线程是进程中代码的不同执行路由。 进程是相互独立的,但在同一进程中的线程之间共享程序的内存空间(代码段、数据集、堆等)和进程级别的资源(如打开文件和信号)。 调度和切换:线程上下文切换比进程上下文切换快得多。多进程和多线程:

多进程:多进程意味着可以在同一时间在同一计算机系统中执行两个或多个进程。 多进程的好处很明显。 例如,如果在听歌的同时打开编辑器并敲击代码,编辑器和听歌软件的进程之间不会存在干扰。 多线程是指程序包含多个执行流。 这意味着一个程序可以同时运行多个不同的线程来执行不同的任务。 这意味着一个程序可以创建多个并行执行线程来完成各自的任务。浏览器多进程架构:

与当前许多多线程浏览器不同,Chrome浏览器使用多个进程隔离不同的网页。 因此,在Chrome中,选项卡是一个过程。

那么,Chrome为什么要使用多进程体系结构?

浏览器刚设计的时候,当时的网页非常简单,每页的资源占有率非常低,所以一个过程就可以处理多个网页。 而且今天,很多页面越来越复杂。 将所有网页合并到一个进程中的浏览器在稳健性、响应速度和安全性方面存在挑战。 因为如果浏览器中的一个选项卡崩溃,则会导致其他打开的网络APP。 另外,对于线程,由于进程间不共享资源和地址空间,所以安全性上的问题不大,由于多个线程共享同一个地址空间和资源,线程间有可能恶意地修改或获取非法的数据等

浏览器内核:

简而言之,浏览器内核是获取页面内容,通过组织信息、应用CSS、计算和组合,输出最终可视化的图像结果,通常也称为渲染引擎。 综上所述,Chrome浏览器为每个选项卡启用单独的进程,因此每个选项卡都有独立的渲染引擎实例。

浏览器内核是多线程:

浏览器内核是多线程的,线程在内核控制下协同工作以保持同步。 浏览器通常由以下驻留线程组成:

GUI呈现线程基于JavaScript引擎线程时间触发线程事件的线程异步http请求线程GUI渲染线程:

GUI渲染线程负责渲染浏览器界面的HTML元素,并在需要重新绘制界面或通过某些操作进行刷新时执行。 当Javascript引擎运行脚本时,GUI渲染线程已挂起。 也就是说,被“冻结”了。

Javascript引擎线程:

Javascript引擎也称为JS内核,主要负责处理Javascript脚本程序,如V8引擎。 Javascript引擎线程当然会分析Javascript脚本并执行代码。

Javascript是单线程的:

既然Javascript是单线程的,为什么Javascript是单线程的?

这是因为一种名为Javascript的脚本语言诞生的使命。 Javascript处理页面中的用户交互,并处理DOM和CSS样式树,为用户提供动态丰富的交互体验和服务器逻辑交互。 如果JavaScript以多线程方式操作这些UI DOM,则可能会发生UI操作冲突; 如果Javascript是多线程的,则在多线程交互下,UI中的DOM节点可能是关键资源。 假设存在两个线程,同时操作一个DOM,一个负责修改,另一个负责删除,这时浏览器需要确定如何启用哪个线程的执行结果。 当然我们可以通过摇头丸解决上述问题。 但是,为了避免引入锁带来的复杂性,Javascript一开始就选择了单线程运行

id="gui-javascript-">GUI 渲染线程 与 JavaScript引擎线程互斥!

由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JavaScript线程和UI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。因此为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JavaScript引擎为互斥的关系,当JavaScript引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到引擎线程空闲时立即被执行。

JS阻塞页面加载

从上面我们可以推理出,由于GUI渲染线程与JavaScript执行线程是互斥的关系,当浏览器在执行JavaScript程序的时候,GUI渲染线程会被保存在一个队列中,直到JS程序执行完成,才会接着执行。因此如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉

定时触发器线程:
浏览器定时计数器并不是由JavaScript引擎计数的, 因为JavaScript引擎是单线程的, 如果处于阻塞线程状态就会影响记计时的准确, 因此通过单独线程来计时并触发定时是更为合理的方案。

事件触发线程:

当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可以是当前执行的代码块如定时任务、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。

异步http请求线程:

在XMLHttpRequest在连接后是通过浏览器新开一个线程请求, 将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件放到 JavaScript引擎的处理队列中等待处理。

参考资料:https://imweb.io/topic/58e3bfa845e5c13468f567d5、http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html

2、V8引擎原理详解

Google V8 引擎使用 C++ 代码编写,实现了 ECMAScript 规范的第五版,可以运行在所有的主流操作系统中,甚至可以运行在移动终端 ( 基于 ARM 的处理器,如 HTC G7 等 )。V8 最早被开发用以嵌入到 Google 的开源浏览器 Chrome 中,但是 V8 是一个可以独立的模块,完全可以嵌入您自己的应用,著名的 Node.js( 一个异步的服务器框架,可以在服务端使用 JavaScript 写出高效的网络服务器 ) 就是基于 V8 引擎的。

和其他 JavaScript 引擎一样,V8 会编译 / 执行 JavaScript 代码,管理内存,负责垃圾回收,与宿主语言的交互等。V8 的垃圾回收器采用了众多技术,使得其运行效率大大提高。通过暴露宿主对象 ( 变量,函数等 ) 到 JavaScript,JavaScript 可以访问宿主环境中的对象,并在脚本中完成对宿主对象的操作。

图 1. V8 引擎基本概念关系图 ( 根据 Google V8 官方文档 )

handle:

handle 是指向对象的指针,在 V8 中,所有的对象都通过 handle 来引用,handle 主要用于 V8 的垃圾回收机制。

在 V8 中,handle 分为两种:持久化 (Persistent)handle 和本地 (Local)handle,持久化 handle 存放在堆上,而本地 handle 存放在栈上。这个与 C/C++ 中的堆和栈的意义相同 ( 简而言之,堆上的空间需要开发人员自己申请,使用完成之后显式的释放;而栈上的为自动变量,在退出函数 / 方法之后自动被释放 )。持久化 handle 与本地 handle 都是 Handle 的子类。在 V8 中,所有数据访问均需要通过 handle。需要注意的是,使用持久化 handle 之后,需要显式的调用 Dispose() 来通知垃圾回收机制。

作用域 (scope):

scope 是 handle 的集合,可以包含若干个 handle,这样就无需将每个 handle 逐次释放,而是直接释放整个 scope。

在使用本地 handle 时,需要声明一个 HandleScope 的实例,scope 是 handle 的容器,使用 scope,则无需依次释放 handle。

上下文 (context):

context 是一个执行器环境,使用 context 可以将相互分离的 JavaScript 脚本在同一个 V8 实例中运行,而互不干涉。在运行 JavaScript 脚本是,需要显式的指定 context 对象。

数据及模板:

由于 C++ 原生数据类型与 JavaScript 中数据类型有很大差异,因此 V8 提供了 Data 类,从 JavaScript 到 C++,从 C++ 到 JavaScrpt 都会用到这个类及其子类

V8 中,有两个模板 (Template) 类 ( 并非 C++ 中的模板类 ):对象模板 (ObjectTempalte) 和函数模板 (FunctionTemplate),这两个模板类用以定义 JavaScript 对象和 JavaScript 函数。我们在后续的小节部分将会接触到模板类的实例。通过使用 ObjectTemplate,可以将 C++ 中的对象暴露给脚本环境,类似的,FunctionTemplate 用以将 C++ 函数暴露给脚本环境,以供脚本使用。

初始化 context 是使用 V8 引擎所必需的过程

V8 引擎使用示例:

有了上面所述的基本概念之后,我们来看一下一个使用 V8 引擎的应用程序的基本流程:

创建 HandleScope 实例创建一个持久化的 Context进入 Context创建脚本字符串创建 Script 对象,通过 Script::Compile()执行脚本对象的 Run 方法获取 / 处理结果显式的调用 Context 的 Dispose 方法

javascript运行环境和机制:

stack 栈:

执行栈,当执行一个函数的时候就会压入栈中,执行完毕后出栈,当执行栈中都执行完毕后就会去轮询事件队列

stack设置了最大长度,当函数调用超过最大的调用限制,浏览器就会报堆栈溢出。

例子:

function a (){ return};function b (){ a();} function c (){ b();}c();

非阻塞(no-blocking)方案:

js是单线程,为了阻塞页面的响应,js里有两种任务:同步任务和异步任务,异步任务有ajax请求、settimeout、响应事件,js中使用回调的方式处理异步任务。真正执行异步任务的是任务类型对应的线程,不是js线程。

执行流程:

V8允许JS遇到异步任务 -->  将异步任务交给对应的线程 --> 继续执行同步任务 --> 其他线程执行完异步任务后,将结果push进事件队列当中 --> 执行栈中的同步任务执行完毕后轮询事件队列,并取出第一个任务执行

 

 

参考资料:https://www.cnblogs.com/wxmdevelop/p/10315622.html、javascript运行环境和机制

 

 

https://imweb.io/topic/58e3bfa845e5c13468f567d5

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。