浏览器底层,内存分配,运行机制

浏览器底层

今天记录一下新学到的知识,浏览器底层原理,这是一条故事线,我们从双击谷歌浏览器开始。
  • 打开浏览器后,操作系统分配内存给浏览器。
  • 浏览器拥有多个进程
    浏览器进程:
    1 Brower 浏览器自身的一些功能
    2 GPU 处理不同tab的内容渲染到统一显示区域
    3 Renderer tab页内的网页展示,js代码运行在此进程
    4 Plugin 控制网页使用的所有插件
  • 我们没开启一个tab就会创建一个Renderer进程,如何验证?
    我们同时按住shift + esc 打开任务管理器
    在这里插入图片描述
    从图中可以看到百度和知乎有不同的进程ID,我们思考一下浏览器这样设计的意义在哪里?当然设计者有自己的想法,我简单聊一聊我们浏览器的同源策略。我们从进程开始说起,我们在操作系统的书上可以了解到进程是资源分配的最小单位,资源有很多了,比如磁盘内存等等,这时候我们来关注内存,可以从上面这句话知道,每一个进程之间的内存是相互独立的,并且每一个进程中的线程是共享内存的。如果知乎和百度在同一进程中,我们在百度的tab上通过网络请求回来的数据,知乎也能够读取到,这样就违背了我们的同源策略,所以每一个tab会开启不同的进程。浏览器为了节约内存,也会把同源的但是不同tab的分到一个进程里面。(这一段是我自己结合然后理解的,欢迎大家的指正)
我们继续浏览器打开的流程
  • 我们重点关注Renderer进程,这就是我们所看到的网页区域。它拥有自己的五个线程。这里就是我们面试经常遇到的问题,从url到显示完成。
    1 GUI
    2 JavaScript引擎
    3 定时触发器
    4 事件触发
    5 异步http请求
1.GUI渲染线程

主要负责页面渲染,解析HTML,CSS,构建DOM树,布局,绘制。重绘回流也会执行该线程,与JS引擎线程互斥,遇到JS代码需要执行时,GUI会被挂起知道任务队列为空。

2.JS引擎线程

负责处理和执行JS脚本。因为互斥关系,JS不能够堵塞,不能页面会卡顿。这里也会出现一个事件队列的问题,我们的代码有同步任务和异步任务,我们都知道同步任务优先级高于异步任务,除开宏任务中的同步任务,微任务高于异步任务。

  • 事件队列,EventLoop
    当我们在解析HTML的时候,遇到JS脚本,首先看是否拥有defer和async属性。这里的执行阶段与DOM解析阶段一定是互斥的,但是加载不用互斥,因为加载是浏览器进程完成的。
    1 如果没有,阻塞GUI,开始加载并执行JS脚本;
    2 拥有async,异步加载与执行JS脚本;
    3 defer同样异步加载,但是会在DOM元素解析完成之后执行JS脚本。
    引用一张别人大神的图片
    在这里插入图片描述
    说回事件队列和事件循环,在执行JS阶段的时候,这时候会出现同步任务和异步任务(ajax
    微任务:promise,process.nextTick(node)
    宏任务:setTimeout,setInterval,I/O,setImmediate(node)
    遇到异步任务之后会将该任务添加到异步队列中并不会立即执行。待全部的同步任务执行完毕之后,来到异步任务队列,这个时候就会根据宏任务和微任务来判断哪一个任务优先执行。在每次执行完宏任务之后,会去清空微任务。
    会优先执行微任务,然后在执行宏任务。执行完之后GUI线程渲染。这个时候会不断的去事件队列取出任务,直到为空为止。
    一定要自己深入去想,事件队列是跟事件有关系的,是指的在那同一刻是按照这样的顺序执行。
    这里我们还能看到一个ajax,我们查不到他的资料,他到底是宏还是微?我们做一个思考,ajax的请求和响应是有时间的1.5个RTT的三次握手,然后传输数据,会耗时,这个时候JS引擎执行宏微时,任务队列并没有把其添加进去。不太理解这个地方,需要查阅更多资料。
3.定时器线程

负责处理异步定时器,JS引擎遇到定时器后,交给该线程,计数完毕后将回调任务添加到事件队列末尾等待JS执行。

4.事件触发线程

将准备好的事件交给JS引擎执行,定时器回调,用户触发的事件,ajax请求的回调。

5.异步http请求线程

负责异步请求,promise,ajax等,异步请求返回结果时,将回调函数加入到任务队列末尾,等待JS执行。

接下来我们来完成面试官的考题相信大家就会很清楚了,url地址输入后,首先要做的就是把域名变成ip地址,我们会先到浏览器缓存中查看是否有该域名对应的资源。这个地方又会涉及到一个新的问题就是浏览器缓存,通常指的是协商缓存强缓存,强缓存会在上一次响应头中检测到cahe-control:max-age=31536000,public,immutable,根据时间判断此次的请求是否使用该缓存,如果超时,就会下一步协商缓存。如果是协商缓存响应头
etag: ‘5c20abbd-e2e8’
last-modified: Mon, 24 Dec 2018 09:49:49 GMT

,这时候就会去host文件中查找域名和ip地址的对应关系,如果没有就本地DNS服务器解析,如果也没有就去更外层的DNS服务器解析,解析完成之后我们拿到ip地址就可以发起http请求了(首先三次握手,http请求响应,四次挥手)。根据http版本的不同我们会有不同的传输方式,http1.0是短链接,一般来说,一次http请求响应就会经历三次握手四次挥手,http1.1改进了加入了keep-live机制,在约定下传输的时间或者传输http个数,时间或者个数一到就会四次挥手。http2 有更大的改观,使用了头部压缩,二进制帧传输,多路复用的技术,让请求响应速度加快。我们拿到对应的html,css,js之后,我们的浏览器开始了渲染工作,从解析html,css,到遇到js脚本后挂起,执行完js后在继续解析(可能会导致重绘,回流),解析完成之后,就要利用GUI线程渲染我们的页面了,但是我们页面可能使用了z-index属性,这个时候,GPU进程就会帮助我们叠加这些不同的渲染层,让我们看到最终的效果。如果没有请求了,http连接也会断开。

终于来到最后一个部分了,内存的分配

我们来看看JS和汇编的联系。

我们大部分人都知道JS有8种类型,7种基本类型(undefined,null,Number,String,Boolean,Symbol,BigInt),1中引用类型(Object),也都知道基本类型的数据存在于栈区,引用类型的地址存在栈区,内容存在堆区中,那我们的函数他是如何存储的呢?它肯定是引用类型,用函数名 instanceof Object 得到true
在汇编语言中,我们的内存主要分为
代码段:执行代码的一块内存
数据段:静态内存,已初始化的变量
BSS段:静态内存,未初始化的变量
:动态分配的内存段,大小不定
:存放局部变量
那我们的JS怎么办呢?前面说过,Renderer进程有有一块自己的内存,我们知道JS引擎是在Renderer进程中的一个线程,那这个JS引擎就会分配和使用这一块内存,就会用来存储我们的变量,代码执行等等。和汇编书中讲的还是有一些差别。
主要分为:

  • ECstack 执行环境栈,负责代码的执行区域。
  • EC 执行上下文,区分不同的作用域
  • VO 存储变量的空间,全局上下文
  • AO 存储变量的空间,私有上下文
    在这里就会产生一个问题,如果我在自己的作用域中并没有找到改变量怎么办?我们就会根据作用域向外部一层一层查找直到找到为止,这就是作用域链

写不完了,要吃饭了。吃完继续写。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该内存不能为“read”或“written解决方案 运行某些程序的时候,有时会出现内存错误的提示,然后该程序就关闭。 “0x????????”指令引用的“0x????????”内存。该内存不能为“read”。 “0x????????”指令引用的“0x????????”内存,该内存不能为“written”。 一般出现这个现象有方面的,一是硬件,即内存方面有问题,二是软件,这就有多方面的问题了。 故障分析 硬件方面: 一般来说,内存出现问题的可能性并不大,主要方面是:内存条坏了、内存质量有问题,还有就是 2 个不 同牌子不同容量的内存混插,也比较容易出现不兼容的情况,同时还要注意散热问题,特别是超频后。你 可以使用MemTest 这个软件来检测一下内存,它可以彻底的检测出内存的稳定度。 假如是双内存,而且是不同品牌的内存条混插或者买了二手内存时,出现这个问题,这时,就要检查是不 是内存出问题了或者和其它硬件不兼容。 软件方面: 先简单说说原理:内存有个存放数据的地方叫缓冲区,当程序把数据放在其一位置时,因为没有足够空间, 就会发生溢出现象。举个例子:一个桶子只能将一斤的水,当放入两斤的水进入时,就会溢出来。而系统 则是在屏幕上表现出来。这个问题,经常出现在 windows2000 和 XP 系统上,Windows 2000/XP 对硬件的 要求是很苛刻的,一旦遇到资源死锁、溢出或者类似 Windows 98 里的非法操作,系统为保持稳定,就会出 现上述情况。另外也可能是硬件设备之间的兼容性不好造成的。 几个例子 例一:打开 IE 浏览器或者没过几分钟就会出现"0x70dcf39f"指令引用的"0x00000000"内存。该内存不能为 “read”。要终止程序,请单击“确定”的信息框,单击“确定”后,又出现“发生内部错误,您正在使用的其中 一个窗口即将关闭”的信息框,关闭该提示信息后,IE浏览器也被关闭。 解决方法:修复或升级 IE 浏览器,同时打上补丁。看过其中一个修复方法是,Win2000 自升级,也就是 Win2000升级到Win2000,其实这种方法也就是把系统还原到系统初始的状态下。比如你的IE升级到了6.0, 自升级后,会被IE5.0代替。 例二:在windows xp下双击光盘里面的“AutoRun.exe”文件,显示“0x77f745cc”指令引用的“0x00000078”内 存。该内存不能为“written”,要终止程序,请单击“确定”,而在Windows 98里运行却正常。 解决方法:这可能是系统的兼容性问题,winXP 的系统,右键“AutoRun.exe”文件,属性,兼容性,把“用 兼容模式运行这个程序”项选择上,并选择“Windows 98/Me”。win2000如果打了SP的补丁后,只要开始, 运行,输入:regsvr32 c:\winnt\apppatch\slayerui.dll。右键,属性,也会出现兼容性的选项。 例三:RealOne Gold关闭时出现错误,以前一直使用正常,最近却在每次关闭时出现“0xffffffff”指令引用的 “0xffffffff”内存。该内存不能为“read” 的提示。 解决方法:当使用的输入法为微软拼音输入法 2003,并且隐藏语言栏时(不隐藏时没问题)关闭 RealOne 就会出现这个问题,因此在关闭 RealOne 之前可以显示语言栏或者将任意其他输入法作为当前输入法来解 决这个问题。 例四:我的豪杰超级解霸自从上网后就不能播放了,每次都提示“Ox060692f6”(每次变化)指令引用的 “Oxff000011”内存不能为“read”,终止程序请按确定。 解决方法:试试重装豪杰超级解霸,如果重装后还会,到官方网站下载相应版本的补丁试试。还不行,只好 换就用别的播放器试试了。 例五:双击一个游戏的快捷方式,“Ox77f5cdO”指令引用“Oxffffffff”内存,该内存不能为“read” ,并且提示 Client.dat程序错误。 解决方法:重装显卡的最新驱动程序,然后下载并且安装DirectX9.0。 例六:一个朋友发信息过来,我的电脑便出现了错误信息:“0*772b548f”指令引用的“0*00303033”内存,该 内存不能为“written”,然后QQ自动下线,而再打开QQ,发现了他发过来的十几条的信息。 解决方法:这是对方利用QQ的BUG,发送特殊的代码,做QQ出错,只要打上补丁或升级到最新版本, 就没事了。 例七:我的笔记本电脑用的XP系统,有时关闭网页时会弹出tbrowser.exe遇到问题需要关闭,然后有弹出 0x03e7c738指令引用的0x03e7c738内存,该内存不能为read,请问是怎么回事? 解决方法:先查杀一下病毒,另外如果你安装了浏

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值