v8引擎垃圾回收机制

内存分配

js中存在基本类型和引用类型,两种类型会存储到不同的区域。基本类型的值存储到上下文中,也就是存储在栈内存中;引用类型的值会存储到堆内存中,该内存的地址会存储到栈内存中,按地址引用。

栈中的垃圾回收

栈中数据存储到上下文中,当一个上下文执行完毕后,指向当前执行上下文的指针会下移,表示上层上下文所占内存可被覆盖。有新的上下文时,就可在使用该内存。

堆中的垃圾回收

分区

堆被分为两个区域:新生区、老生区。根据所要存储对象的大小、存活时间存入相应分区。大的对象、存活时间长的对象会存储在老生区,小的对象存储在新生区。新生区和老生区有相同的垃圾回收流程,但使用不同的垃圾回收策略。

垃圾回收流程

  • 标记内存中活动对象和非活动对象。
  • 清理非活动对象所占的内存。
  • 清理后会出现碎片化的内存空间,需对内存做整理。

垃圾回收策略

新生区

  • 新生区容量很小,被均分为两部分,分别为对象区域和空闲区域。
  • 新生区通过副垃圾回收器进行垃圾回收。
  • 新的小对象会被存入对象区域。
  • 对象区域满的时候,进行标记,之后清除垃圾所占内存。
  • 将存活的活动对象赋值到空闲区域,整理碎片化内存。此时,空闲区域和对象区域角色互换。不断进行下去,实现内存的复用。
  • 在新生区中存活时间超过两轮的小对象会被传入老生区存储。

老生区

  • 老生区存储大对象和存活时间长的对象。
  • 老生区通过主垃圾回收器进行垃圾回收,采用标记清除法。
  • 从一组根元素开始递归遍历上下文栈,被引用的为活动对象,否则为非活动对象。
  • 在下次内存清理时清理。
  • 之前的清理方法会产生碎片化内存。可能无法给后续大对象分配连续的内存空间。
    另一种策略—标记整理法可解决该问题。在标记之后,先把活动对象向一端移动,然后清理端边界之外的内存。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。