4-2 内存图与JS世界(进程与线程、JS引擎、内存图、JS原型)

一、进程与线程

1.英语小课堂

  • Operating System 操作系统,简称OS
  • runtime 运行时(运行时你所需要的所有东西)
    JS运行的时候需要浏览器,那么浏览器就会提供一个运行时给JS
  • environment 环境,简称env
  • person 一个人
  • kernel 内核
  • compile 编译
  • memory 记忆、存储
  • people 一群人(person的复数)

2.操作系统常识
一切都运行在内存里
2.1 开机
通电——读固件——加载开机程序——操作系统被加载到程序里

  • 操作系统在C盘里(macOS的在根目录下多个目录里)
  • 当你按下开机键,主板通电,开始读取固件
    固件:固定在主板里的内存卡,里面写死了主板的程序
  • 开机程序就会将文件里的操作系统加载到内存中运行

2.2 操作系统被加载到内存以后做什么?(以Linux为例子)
操作系统的内核叫kernel
提供给用户的操作界面叫shell

  • 首先加载操作系统内核
    预先加载所有最重要的功能,例如:上网模块、文件管理、操作显示器,操作系统把最基本的功能嵌入了内核,就不用额外打开程序就可以用。
  • 然后启动初始化进程,编号为1,每个进程都有编号
    进程:一个exe文件双击后就可以启动一个进程
    任务管理器——PID
    如:某程序PID=1120,表示该程序是在电脑上第1120个打开的程序
  • 启动系统服务:文件、安全、联网
  • 等待用户登陆:输入密码登陆/ssh登陆
    ssh:远程登陆
  • 登陆后运行shell,用户就可以和操作系统对话了
    Windows系统登陆后就是桌面,而Linux系统登陆后会有一个黑框用来输入命令
  • bash是一种shell,图形化界面可认为是一种shell
    cmder里面就有bash,bash是一个ba的人写的shell
    图形化界面:也就是桌面,可以通过鼠标点击

2.3 打开浏览器
2.3.1 chrome.exe
在这里插入图片描述

  • 双击Chrome图标,运行Chrome文件
  • 双击开启Chrome进行,作为主进程
  • 主进程会开启一些辅助进程,如网络服务、GPU加速
  • 用户每新建一个网页,就有可能开启一个子进程

2.3.2 浏览器的功能

  • 发起请求,下载HTML,解析HTML,下载CSS,解析CSS,渲染界面,下载JS,解析JS,执行JS等
    如:浏览器输入baidu.com
    1.向百度服务器发起请求,下载对应的HTML,得到一个文本,读取HTML,HTML引用了一个CSS,就去下载CSS解析。
    2.渲染:HTML和CSS解析完要合起来,HTML提供节点,CSS提供节点的样式,合起来显示屏幕上
    3.HTML引用了JS,下载读取JS,边解析边执行。(执行就是把命令打印到控制台)
  • 浏览器完成以上功能的模块:用户界面、渲染引擎JS引擎、存储等
    渲染引擎:就是把得到的HTML和CSS合起来,渲染得到一个界面的代码。引擎不是发动机而是一个代码,就是把代码运行起来。(HTML和CSS公用一个引擎是因为HTML是有默认样式的,因此要放在一起)
    JS引擎:解析并执行JS(下载是网络模块执行)。
    JS是怎么渲染的?
    答:线程通信,JS要修改HTML或者CSS,不能直接修改,要通过线程之间的通信来通知渲染引擎,这叫做跨线程通信。(谷歌会提供通信接口)
    跨线程通信要比线程馁慢,所以DOM操作慢。
  • 上面功能模块一般各处于不同的线程(比进程更小一级的东西)
    理解:例如百度打开一个知乎网页,知乎网页这个页面上运行渲染引擎和JS引擎,知乎已经是一个进程了,而这两个引擎在知乎页面内运行,成为线程。
    每一个页面都会开启一个渲染线程和JS线程。
    JS是单线程的
  • 如果进程是车间,那么线程就是车间里的流水线

二、JS引擎

1.JS引擎举例
现在说引擎默认V8

  • Chrome用的是V8引擎,C++编写
    作者写了8个引擎,第8个是给JS写的。
    C++是性能王者
  • 网景用的是SpiderMonkey,后被Firefox使用,C++
    蜘蛛猴
  • Safari用的是JavaScriptCore
  • IE用的是Chakra(JScript9)
    查克拉,用的查克拉的JS版本
  • Edge用的是Chakra(JavaScript)
    IE12用的查克拉的JS版本
  • Node.js用的是V8引擎

2.JS引擎的主要功能

  • 编译:把JS代码翻译为机器能执行的字节码或机器码
    机器码是二进制,字节码是二进制再转一次
  • 优化:改写代码,使其更高效
  • 执行:执行上面的字节码或者机器码
  • 垃圾回收:把JS用完的内存回收,方便再次使用
    将用完的变量回收,下次再申请变量时再用

3.执行JS代码
在执行代码之前,浏览器需要做什么
1.准备工作

  • 提供API:window / document / setTimeout
    在这里插入图片描述
  • 以上都是浏览器提供给JS的功能,不是JS自身具备的功能
  • 将这些功能(如window)称为运行环境 runtime env
  • 一旦把JS放进页面,就开始执行JS

2.深入研究

  • JS代码在哪里运行?
    答:内存。一个HTML引用了JS,下载后代码放到内存里。
  • 代码放到哪个内存里?
    答:下方内存图解释

三、内存图

3.1 瓜分内存

  • 当操作系统运行后,所有的东西都会进入8G内存里
  • JS引擎瓜分内存:代码区(存代码的)
  • 不知道什么区abc:存储变量,存下环境,代码区里面的a存入这个区,数字1存到红色区域
  • stack(栈区):数据区的stack
  • heap(堆区):数据区的heap
    在这里插入图片描述

3.2 红色区域

1.作用

  • 红色专门用来存放数据,我们目前只研究该区域
  • 红色区域并不存变量名,变量名在[不知什么区](绿色区域)
  • 每种浏览器的分配规则不一样
  • 除了上图标出来的还有:调用栈、任务队列等区域

2.Stack和Heap

  • 红色区域氛围Stack栈和Heap堆
  • Stack区特点:每个数据顺序存放(不准跳格存放)
  • Heap区特点:每个数据随机存放(每次都随机找位置开辟区域存储,要是之前存的内容后面的位置占了,想要扩大时就重新找个位置存,前面的释放掉)

3.3 Stack和Heap举例
1.代码

var a = 1
var b = a
//把a对应的内存里面的数据直接拷贝到b,数值就直接存,对象就拷贝地址
var person = {name:'frank',child:{name:'jack'}}
//只要是个对象都要开辟新空间来存,因此child里面的不能直接存到child那块内存里,把内存的地址发发你感到child中
  • a在不知什么区存储,数据1(64位)存储在stack区域中,当 b=a时,把a对应的内存里面的数据直接拷贝到b,纯拷贝
  • person(简称p)中的对象存储在heap中的随机区域,其中child中的对象(对象中的对象)另外开辟地址存放(所有的对象都要开辟新空间来存),后续将地址发到child中即可
  • p在stack中存储对象的地址即可,p2同理与上面的b
  • 当 p2.name=‘x’,p.name=?
    答:p2根据#108找到相应对象并修改,而地址不变,因此p对应的对象内容也修改,应该也是x
  • 为什么p中的对象要存在Heap?
    答:如果内容存在Stack时,由于按照顺序存放,person中再加内容(如加一行:p.age=18),p后面已经有占位了,就无法再添加进新的东西,而Heap是随机存放,大多数时候后面都是没有对象的,因此可以添加。

在这里插入图片描述
2.规律

  • 数据分两种:非对象和对象
  • 非对象都存在Stack(数字、字符串、布尔)
  • 对象都存在Heap(数组、函数等)
  • =号总是会把右边的东西直接左边(不存在什么传值和传址)

3.区分值和地址
会画内存图就不需要区分值和地址

JS世界

JS写第一行代码前的内存长什么样?
1.JS开发者说要有全局对象window,所以浏览器就提供了window

2.还要什么?

  • console:挂到window上,window.console
  • document:挂到window上,window.document
  • object:对象,挂到window上,window.object,其中var person = {}等价于var person = new Object()
  • array:数组,挂到window上,window.array,其中var a = [1,2,3]等价于var a = new Array(1,2,3)
  • function:函数,挂到window上,window.function,其中function f(){}等价于new Function()

在开始开始写代码之前至少有5个对象都挂到window上
上面的等价式后者是正规写法,但没人用,前者不正规但好用,简写更好用。
在这里插入图片描述
3.挂在window上的原因
方便,挂在window上的东西可以在任何地方直接用
把window用内存图画出来。(对象只有地址,没有名字)
在这里插入图片描述
更加简化的画法

  • 对象是没有名字的:一个对象只有地址,没有名字,如Heap中的对象开辟了一个区域地址为#90
    而只是因为其地址Stack存下来了,其中window在不知道什么区,内容在Heap区,它们是通过stack中的地址联系起来而已,所以认为window是它的名字。
    因此下图中的对象名不属于这块内容。
  • window.console指向/引用了某个对象。(console保存了那个对象的地址)
    指向/引用:保存了其地址在这里插入图片描述
    总结该图:
  • window有三个属性,第一个属性指向console;第二个属性Object指向了一个函数,函数有两个属性;Array指向了一个对象,对象也有两个属性(一般第一个字母大写就会有prototype)。
  • object是个函数,可以创造一个新的对象,console.dir(window.object),其中dir的意思是打出它的结构
    在这里插入图片描述

4.细节

4.1 关于window

  • window变量和window对象是两个东西(变量是在不知道什么区,对象是在#90号内存),只是恰巧变量保存了对象的地址,变量和对象没什么关系
  • window变量是一个容器,存放window对象的地址。(可以存放不同的地址)
  • window对象是Heap里面的一坨数据
  • 当让var x = window,那么x就指向了window对象,那么window变量就可以不要了,如 x.console,但容易弄混,尽量不要这样改。

4.2 同理

  • console和console变量不是同一个东西
    console是window里面存的一个属性,#90号地址的第一行就是console,而console对象在#28号
  • object和object函数对象不是同一个东西
  • 前者是内存地址,后者是一坨内存
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值