浏览器杂学 | 青训营笔记

58 阅读3分钟

程序&进程&线程

程序

程序是一个静态的实体,储存在磁盘里。(本质上是某个数据的集合)比如我写完一串C语言代码,编译完成后会生成一个.exe文件,这就是储存在磁盘中的一个程序。

进程

进程是一个动态的实体,是程序的执行,加载在内存中。比如我点开一个.exe程序,它就会在内存里加载出一个进程。多个进程之间是并发的关系而不是并行的关系。进程之间不共享内存,使之交互变得困难,同时多个进程以及子进程会导致内存的浪费。

线程

线程是CPU的最小执行单位,一个进程可以有多个线程。同一进程下多个线程之间也是并发关系且共享内存,极大地提高了程序的运行效率

浏览器架构和事件循环

现代浏览器架构

多进程:主进程负责浏览器界面,用户交互,管理子进程,提供储存功能等,此外还有插件进程,网络进程,GPU进程,渲染进程(内核)等

事件循环的作用

让渲染引擎与JS引擎相互配合,确保JavaScript单线程的同时防止HTML解析与页面渲染的堵塞

异步以及它的实现

  • 异步是指不在主线程执行,而是通过任务队列通知主线程,达成不等任务执行完,直接执行下一个任务。
  • 将一个耗时长的任务(定时器,网络请求,用户交互等)从主线程里剔出放入任务队列里,等待主线程任务完成后进行事件循环再将该任务拿回来执行

变量

一个进程可以大致分为两大部分,代码段(text)和数据段(stack(栈)+heap(堆)+data(JS没有data段))。

栈(stack)的特点:

  • 结构性强,内存连续
  • 寻址速度快
  • 数据稳定(每一个数据的大小都是确定的(IEE754(64位))
  • 容量小

栈里面存的东西有两种,一种是基本数据类型,另一种是引用数据类型的标识符(因为程序只允许访问栈而不能访问堆,(没有访问堆的权限)所以要通过栈通过标识符来间接的访问堆)

堆(heap)的特点:

  • 类似于书架(里面存储的数据可以直接的随意的查取)
  • 存储以为单位的数据
  • 容量大(堆和栈的容量大小总量一定,通常会把堆的容量设计得大一些)
  • 不同数据间内存不连续

JS中的变量类型

  • 原始类型(primitive type):

    基本数据类型(原始类型)一般存在栈里。基本数据不可修改(基本类型存在栈里,每次会增加一个新的内存而不能直接改动原来的数据)

  • 引用类型(reference type):

    JS里的引用类型就是对象,对象存在堆里。(存在堆里的原因:对象大小不确定,它可能会拥有很多很多的属性、数据)

    对象是JS中唯一可变的值。(函数也是对象)

    var
    r1 = {
        a: 1,
    },
        r2 = r1;r2.a = 2;
    console.log(r1.a, r2.a);
    

    以上代码实现方式:先在栈里面压入了一个变量被标记为r1,它存的值是后面的对象在堆内存的地址。然后r2 = r1则是把r1的地址赋给了r2(因为只能访问栈),所以r1和r2都指向了堆里面的a,现在r2.a = 2则是直接把a的值进行了修改,所以r1与r2的值均发生改变。

关于字符串:根据ECMA规定,字符串是基本类型,存在栈里,但实际上的使用需要用到堆,比如下面这串代码:

var a = 'hello world';
b = a;
b = 'hello';
console.log(a,b);

值传递和引用传递

例:

function change1(arg){
    arg = 200;
}
​
function change2(arg){
    arg.a = 200;
}
​
var foo = 100;
var bar = { a: 100 };
​
change1(foo);
change2(bar);
​
console.log(bar.a);
console.log(foo, bar);

打印结果为:

100

200