文章目录
进程和线程
简单理解进程就是一个程序需要用到的内存资源空间,线程就是在这个进程内干活的“人”,一个人就是一个线程。
下面引用不看也ok
创建程序时,就会创建一个进程,并把进程的状态保存在内存空间里,进程可以启动更多同级的进程,且分配的内存空间相互独立。进程间需要通过进程间通信管道IPC来传递。进程相互独立,所以其中一个出问题,整个程序仍然可以正常运行。进程可以创建多个线程去并行执行不同任务,同一进程下的线程之间可以相互通信;
浏览器
多进程
浏览器可以同时出现多个进程,多个进程好处是哪个崩了,另外的进程能不受影响,可以通过浏览器的更多工具里找到-任务管理器看到每个进程。
分别有如下
浏览器进程
浏览器的主进程(负责协调、主控),只有一个。
作用:
- 协调其他进程工作,创建和销毁其他进程,属于老大哥。
- 负责浏览器界面显示(不是页面内容哦),用户交互(如点击、前进,后退、滚动等)。
网络进程
负责发送接收网络请求。
GPU进程
负责界面渲染,用来做3D绘制,一个浏览器只有一个GPU进程。
插件进程
负责控制网站使用所有插件(例如flash、不是指扩展插件)
渲染器进程
即浏览器内核,用来控制显示tab标签内的所有内容,一般情况是每个页面都有一个渲染器进程的模式,所以每个页面都是独立互不干扰的,但也相对耗费资源。
渲染器进程会开启一个主线程,主要作用页面渲染,脚本执行,事件处理等,这是我们需要重点关注的。
内核(渲染器进程)
浏览器的一些发明时间:95年IE问世,03年Safari问世,04年网景旗下的Mozilla基金会推出火狐,05年苹果把webkit开源,08年谷歌使用webkit改造优化成为blink发明Chrome,15年微软放弃IE使用webkit推出Edge。
渲染引擎(内核、渲染进程),各浏览器内核:
- IE:Trident
- Firefox:Gecko
- Safari:Webkit
- Chrome/Opera/Edge:Blink
内核有以下线程(好像统称主线程)
GUI渲染线程
负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。
JS引擎线程
也称为JS内核,负责处理Javascript脚本程序。
事件触发线程
用来控制事件循环
定时触发器线程
setInterval与setTimeout所在线程
异步http请求线程
在XMLHttpRequest在连接后是通过浏览器新开一个线程请求 (ajax请求)
JS引擎
简单解释
JS引擎可以粗略理解为是把JS转成机器语言的程序,比如谷歌的 V8、webkit的JavaScriptCore、火狐使用的SpiderMonkey、QuickJS、facebook在React Native使用的Hermes;
引擎的解析过程从宏观来看大致为:先把JS通过parser(解析器)解析成抽象语法树AST,再通过interpreter(解释器)解释成字节码bytecode,它是一种跨平台的中间表示,可以在不同的操作系统运行,再通过compiler(编译器)生成机器代码(汇编),这个编译器还会根据不同的处理器平台(IA32、X64、ARM、MIPS)编译出对应的机器代码(汇编);
V8怎么运行JS
V8被运用在谷歌浏览器,node的运行环境也是V8,electron的底层引擎也是V8等等,所以JS可以运行在不同的环境上;
V8由C++编写,大致是一个接受JS代码,编译代码然后执行的C++程序,编译后的代码可以在多种操作系统多种处理器上运行;
最新的V8大致工作为,先把JS通过parser(解析器)解析成抽象语法树AST,然后通过Ignition(基准解释器)生成解释成字节码bytecode,删除AST,释放内存空间,Ignition直接执行bytecode且以bytecode作为基本执行模型,此时的bytecode很接近准机器代码了,大小几乎等效机器代码的25%-50%;在JS的运行过程中,解释器收集有没有可以优化代码的信息,然后发送给TurboFan(优化编译器),然后根据bytecode优化出机器代码;
其中优化编译器的一些策略,比如函数只声明但不调用,就不会生成AST;比如同个函数需要执行多次,优化编译器才能收集信息去优化,所以只调用一次的函数,bytecode直接被解释执行;比如同个函数被调用多次,就会被标记成热点函数,每次执行这个函数时,直接执行优化编译器优化后的机器代码;例如JS因为是动态语言,所以优化编译器会把机器语言再回退成bytecode,然后再让基准解释器来解释执行(例如同个函数前面一直传的参数为数字类型,就会被优化成机器语言,但突然传字符串,则就会回退),所以不要因为JS开放就变来变去的,会给引擎带来负担;
为什么要先成中间的bytecode,因为生成这个比机器码快得多,而且还可以直接执行。还有就是因为动态而重新编译的过程直接为bytecode与优化后的机器码的转换,所以JS运行速度才能得到再次的提升;