【Javascript 的内存机制】
--------------Javascript 的内存机制 -------------
支持隐式类型转换的语言称为弱类型语言
不支持隐式类型转换的语言称为强类型语言
1、JavaScript 内存空间--三种类型: 代码空间、栈空间、堆空间
①栈空间--是调用栈,存储执行上下文
②堆空间
对象类型是由堆来存储,栈上存储的是对象在堆上的引用地址 (堆上的空间比较大)
原始数据类型直接保存在栈中
函数的闭包(变量的集合是存储在堆上,所以函数出栈了,但是闭包仍可以被调用)
③代码空间:存储可执行代码
----------------垃圾数据的自动回收 ------------
1、调用栈中的数据是如何回收的
当函数执行结束后,JavaScript引擎会通过向下移动ESP(记录当前执行状态的指针)来销毁该函数保存在栈中的上下文
2、堆中的数据是如何回收的
要收回堆中的垃圾数据,就需要用到JavaScript中的垃圾回收器了
2-1、 两种垃圾回收器 : 副垃圾回收器 和主垃圾回收器
2-2、 V8会把堆中划分为两个区域:新生代和老生代
新生代中存放的是生存时间短的对象,老生代存放的是生存时间久的对象
2-3、副垃圾回收器,主要负责新生代的垃圾回收; 主垃圾回收器,主要负责老生代的垃圾回收
2-4、副垃圾回收器:把新生代和老生代划分为两个区域 【对象区域】和【空闲区域】
①首先对对象区域中的垃圾进行标记,
②然后将存活的对象复制到空闲区域
③完成赋值后,将对象区域与空闲区域进行角色翻转,清空空闲区域的所有垃圾
因为复制耗时,所以为了执行效率,新生代区域的空间不大,且对于进行两次垃圾回收后仍然存活的对象,就会被放置到老生代
2-5、主垃圾回收器:使用标记-清除,标记-整理
①先将对象进行标记,然后清除非活动对象
②然后将内存碎片,进行整理 (所有对象都向一端移动,然后清除掉端边界意以外的内存)
因为老生代的对象比较大,所以执行时间比较久,会造成页面卡顿,全停顿时间比较久,用户体验不好, 所以为了避免这个问题,V8将标记过程分为一个个的子标记过程,同时
让垃圾回收和Javascript应用逻辑交替进行,直到标记阶段完成,we call this action as 增量标记 (Increment Marking)