内存图与Js世界

183 阅读4分钟

本章介绍科班必备的基础常识,包括操作系统,浏览器,内存等。


一、一切运行都在内存里

开机

  • 操作系统在C盘,(macOs在根目录下多个目录里)
  • 当你按下开机键,主板通电,开始读取固件
  • 固件就是固定在主板上的储存设备,里面有开机程序
  • 开机程序会将文件里的操作系统加载到内存中运行

操作系统(以Linux为例)

  • 首先加载操作系统内核
  • 然后启动初始化进程,编号为1,每个进程都有编号
  • 启动系统服务:文件、安全、联网
  • 等待用户登录:输入密码登录/ssh登录
  • 登录后,运行shell(指“为使用者提供操作界面”的软件(命令解析器)),用户就可以和操作系统对话了
  • bash是一种shell

二、打开浏览器

chrome.exe

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

浏览器功能

  • 发起请求,下载HTML,解析HTML,下载CSS,解析CSS,渲染界面,下载JS,解析JS,执行JS等
  • 功能模块:用户界面、渲染引擎JS引擎、存储等
  • 上面功能模块一般各处于不同的线程(比进程更小的单位)
  • 如果进程是车间,那么线程就是车间里的流水线

Q: 既然渲染引擎和JS引擎是分开的,那么JS如何修改CSS和html来更改渲染的?

JS不能直接修改CSS和HTML,需要通过JS引擎跨线程通信来通知渲染引擎

由于跨线程通信比线程内通信要慢,固有这么一句话:

DOM操作慢


三、JS引擎

Js引擎举例

  • Chrome用的是V8引擎,C++编写
  • 网景用的是SpiderMonkey,后来被Firefox使用,C++
  • Safari用的是JavaScriptCore
  • IE用的Chakra(JScript)
  • Edge用的是Chakra(JavaScript)
  • Node.js用的是V8引擎

Js引擎的主要功能

  • 编译: 把JS代码翻译为机器能执行的字节码或者机器码
  • 优化: 改写代码,使其更高效
  • 执行: 执行上面的字节码或者机器码
  • 垃圾回收: 把JS用完的内存回收,方便之后再次使用

四、JS内存分析

Js运行环境

我们需要把JS放入运行环境(runtime env)中,js才可以执行。

浏览器环境下JavaScript主要由三部分组成,分别是ECMAScript、DOM和BOM。

Node.js中以ECMAScript为基础,扩展出了I/O操作、文件操作、数据库操作等。

由以上可以看出,API在运行环境中十分重要,最常用的有window/document/setTimeout



内存分析

红色的为数据区,是重点,主要由Stack和Heap组成,非对象的数据在Stack,对象的数据在Heap(因为对象的数据要求能时时增删改,链式存储满足其规则)

变量在不知什么区,每个浏览器的这个区的名字都不同


非对象是在Stack上存值,当var b=a时,把a的值的内存复制到b的值的内存。

但是对象就是在Stack上存地址,地址指向heap里的随机划分内存,如图。 当var p2=p,是指把p的地址给p2,两者所指向同一随机内存。


注意:window变量和window对象是两个东西,window变量在不知什么区,window对象#90在Heap



prototype原型

1.obj 有一个隐藏属性__proto__

2.隐藏属性存储了Object.prototype对象的地址

3.obj.toString()发现obj上没有toString

4.就去隐藏属性对应的对象里面找

5.于是就找到了Object.prototype.toString

原型XXX.prototype储存了XXX对象的共同属性,让你无需重复声明共有属性,省代码,省内存

每个对象都有一个隐藏属性,指向原型

假如我们想调用arr.hasOwnProperty(),但是Array的原型里冇得hasOwnProperty(),Object的原型里有,事实上,Array的原型里的__proto__会记录Object的原型,这杨两个链找到这个hasOwnProperty()全局属性

Object的__proto__为空,Object最高