Skip to content

面试装逼神器吗?有点意思垃圾回收,对于后端是至关重要的,因为服务的持久性,后端更加容易内存溢出,服务宕机。

V8引擎

Chrome和Node的引擎,栈用来执行函数,这里我们研究==堆==的内存: Pasted image 20251122183625.png

  • Large object space:存储超出默认大小的对象
  • Code space:存储已经编译的代码
  • Cell、Property cell、Map space

垃圾回收机制

垃圾回收机制作用于New Space 和Old Space:

  • 新生代:Copy复制与Scavenge新生代互换
    • 包括From和To这两部分大小相等的空间:
  • 老生代:Mark-Sweep标记清除,Mark-Compact标记整理 Pasted image 20250902212116.png

新生代

代码中定义的变量会优先进入from中,在代码的运行过程中可能会有变量已经不需要,并被标记,当from空间满的时候,GC(垃圾回收机制)会回收被标记的垃圾,之后再加入新的变量,之后将from与to的位置对调(新生代互换),循环往复: Pasted image 20251122182933.png 那为什么要copy呢?因为通过牺牲空间换时间,copy的时间很快

老生代

老生代中的两个区,Old pointer space中保存具有引用的或者被引用的对象。而Old data space保存原型。

垃圾回收时的两个算法:

  • Mark-Sweep标记清除:清除掉标记的垃圾
  • Mark-Compact是==先整理后清除==的,因为整理的时候可能会覆盖掉一些垃圾 Pasted image 20251122183042.png

现在的标记过程并不是一次全部标记,而是多次(增量标记),并且采用三色,增加线程切换的粒度。 Pasted image 20250902220829.png

老生代的对象由新生代晋升而来(经历过对调且to已经使用了25%时): Pasted image 20251122183341.png

他们所占的空间和操作系统有关:64位1464MB,32位732MB(v14已经变为2GB)

JS在设计之初就是做前端的,它是异步单线程的,最开始是没有现的复杂业务场景,并不需要考虑持久化问题。比如大文件文件上传(2G的)最开始并不被考虑。所以没有必要设计如此巨大的空间

查看内存使用情况: 浏览器 Pasted image 20250902221855.png

Node 使用max-old-sapce-size和max-new-sapce-size配置老生代和新生代大小