浏览器底层

今天记录一下新学到的知识,浏览器底层原理,这是一条故事线,我们从双击谷歌浏览器开始。
  • 打开浏览器后,操作系统分配内存给浏览器。
  • 浏览器拥有多个进程
    浏览器进程:
    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. Yarn 内存分配管理机制及相关参数配置

    理解Yarn的内存管理与分配机制,对于我们搭建.部署集群,开发维护应用都是尤为重要的,对于这方面我做了一些调研供大家参考. 一.相关配置情况 关于Yarn内存分配与管理,主要涉及到了ResourceM ...

  2. Gstreamer 内存分配协商机制

    在两个衬垫的caps协商完成之后,元件之间需要确认如何分配buffer.本文梳理Gstreamer 内存协商机制,比如当某元件不能自己分配内存时,如何使用其他元件的分配器. 场景和目的 一般而言,内存 ...

  3. 膜拜大佬!JVM性能调优——JVM内存模型和类加载运行机制

    一.JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包.因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM 是 JRE 的核心组成部分 ...

  4. JVM内存模型和类加载运行机制

    JVM内存模型和类加载运行机制 JVM内存模型 运行一个 Java 应用程序,必须要先安装 JDK 或者 JRE 包.因为 Java 应用在编译后会变成字节码,通过字节码运行在 JVM 中,而 JVM ...

  5. 内存分配算法java_被说烂了的Java垃圾回收算法,我带来了最“清新脱俗”的详细图解...

    一.概况 理解Java虚拟机垃圾回收机制的底层原理,是系统调优与线上问题排查的基础,也是一个高级Java程序员的基本功,本文就针对Java垃圾回收这一主题做一些整理与记录.Java垃圾回收器的种类繁多 ...

  6. 计算机可用内存分配失败,你们都被忽悠了! 其实可用内存大才有用

    [PConline 杂谈]随着这几年安卓手机的硬件快速升级,手机的运行内存(本文后续页面将"运行内存"简称为内存或者RAM)也越来越大,从最初的512M到1GB,再到现在主流的2G ...

  7. JVM源码简析(楔子)-对象内存分配过程和PS回收器中YGC触发FGC的现象

    前言 想要搞明白Java对象内存申请过程的原因,是因为第一次接触线上GC日志的时候,发现了一些很奇怪的现象,就是young gc触发了full gc.为了搞清楚这个现象,得先要来个测试去复现. 复现现 ...

  8. 深入理解JVM内存分配策略

    点击上方 "程序员小乐"关注公众号, 星标或置顶一起成长 每天早上8点20分, 第一时间与你相约 每日英文 Don't blame people for disappointing ...

  9. C++中运行一个程序的内存分配情况及qt中的内存管理机制

    一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一 ...

最新文章

  1. UE4入门学习3:GamePlay框架
  2. java基础 --- Arrays.asList():返回指定数组支持的固定大小列表
  3. (办公)eclipse连接github cannot open git-upload-pack(git-receive-pack)
  4. 实现一个闹钟_iOS 14 闹钟:为啥这么难用?
  5. GPS NAME0183 详解
  6. 《Redis开发与运维》学习第四章
  7. 强化学习入门笔记(一)——莫烦Python
  8. PATHLOSS.4.0 无线电设计软件
  9. 2018WPS暑期实习生web前端笔试题
  10. 最新软件注册码,总有你要的!
  11. 【python技能树】python程序设计思想
  12. 宁皓网bootstrap
  13. 执念斩长河专栏总目录
  14. PAT基础级-黄金段位样卷1
  15. 算法:(二)枚举(穷举)算法
  16. 安装、卸载mysql服务命令
  17. 六种常见的「用户行为」分析方法
  18. 在线压缩转换文件的软件
  19. C/C++浮点数的存储方式 IEEE-754标准,以及实现一个ftoa函数将浮点数转换为字符串
  20. 面向万物智联的应用框架的思考和探索(上)

热门文章

  1. Web表单的十九个最佳设计实践
  2. 西门子1200 总线控制V90伺服程序模板
  3. PHP RSA加密解密
  4. hyperion卫星重访时间_国际资讯|小型雷达卫星的干涉测量技术
  5. 携程2016研发工程师笔试题
  6. MOOC战德臣数据库课程自用笔记_4_SQL概述与简单SQL语句
  7. LabVIEW 读取 tdms文件并存为csv
  8. Motoman机器人离线编程——Motocom32开发简介
  9. 关于单片机使用继电器时为什么要在继电器电路上加接二极管
  10. 一起DIY四轴飞行器(三)添加实时操作系统--freeRTOS