最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 理解 NodeJS 的内存管理机制

    正文概述 掘金(QZhan)   2020-12-10   417

    v8 的内存限制

    众所周知,Node 是基于 v8 引擎来构建的,所以在 Node 中使用的对象基本都是通过 v8 引擎来统一进行内存分配和管理。然而 v8 引擎 本身对内存的使用限制了大小,在64位系统下只能用 1.4GB 的系统内存。

    这个大小足以应付日常的大部分应用程序需要,但为什么 v8 引擎 要限制内存使用的大小呢?

    一方面是因为 v8 引擎最初是为浏览器而设计的。对于页面来说, 很少有需要长时间运行和使用大内存的场景,1.4GB 的内存限制是足够的。

    更重要的原因是 v8 引擎的垃圾回收机制的性能所限制。以内存上限1.4GB 为例子,v8 引擎的垃圾回收机制对于这个数量级别的数据,做一次简单的垃圾回收就需要50ms以上,而在垃圾回收过程中,JavaScript 线程会完全暂停,等待垃圾回收结束。无论对于前端浏览器程序还是后端服务程序来说,这样的时间开销都是不可接受的。因此 v8 引擎限制内存堆的大小,更多是基于性能方面的考虑。

    当然对于特殊场景,v8 引擎也是可以通过启动参数 --max-old-space-size 或者 --max-new-space-size 来调整内存限制的大小。这里的 old-space 和 new-space 就是下文要提到的老生代和新生代内存。

    新生代和老生代

    v8 引擎的垃圾回收策略主要是基于分代式垃圾回收机制。何为分代式呢?就是将内存中的对象按照存活时间长短大致分为两类:新生代老生代

    v8 引擎的堆内存大小就是等于新生代所用内存大小 + 老生代所用内存大小。前面提到的 1.4GB 大小会分出 32MB 的内存大小给新生代空间,剩余的都分给老生代空间。

    新生代和老生代的空间差距这么大,是因为新生代中的对象的生命周期都比较短,新生代对象存在一段时间后往往都会被晋升到老生代空间中去。在晋升机制的保障下,新生代空间一般不会存在太多对象,因此也不需要太多的预留空间。

    新生代垃圾回收算法

    在了解晋升机制前,我们还需要先了解新生代的回收机制。

    新生代使用的垃圾回收算法名为 Scavenge 算法,该算法的核心思想是将堆内存平均分为两份空间,处于使用状态的称为 From 空间,处于闲置状态的称为 To 空间。

    当我们创建对象时,会在From空间分配内存,当开始新生代垃圾回收时,会将From空间的存活对象全部复制到To空间,剩下的非存活对象则全部回收。完成复制后,From空间和To空间的身份互换。如此循环下去,就相当于把存活对象在两个空间之间进行复制。

    Scavenge 算法的缺点就是只能利用新生代空间的一半内存来分配对象,这是一种典型的牺牲空间换取时间的做法。

    在新生代空间中存活对象只占少部分(大部分长期存活对象都被晋升到老生代),由于 Scavenge 算法只复制少量的存活对象,因此它的回收占用时间非常短。

    另外每次从From空间复制对象到To空间前会对对象进行晋升判断,新生代对象的晋升条件有两个:

    1. 该对象是否已经经历过 Scavenge 回收
    2. To空间已经使用了25%的内存

    对象只要满足其中一个条件即可获得晋升。

    老生代垃圾回收算法

    对于老生代中的对象,由于存活对象占较大比重,因此不适合使用 Scavenge 算法。v8 引擎对于老生代空间使用了 Mark-Sweep和Mark-Compact相结合的方式进行垃圾回收。

    Mark-Sweep如名字所示,整个垃圾回收过程分为标记清除两个阶段。Mark-Sweep在标记阶段会遍历堆中的所有对象,并标记存活对象。然后在清除阶段中,只对没有标记的对象进行清除。前面提到老生代空间中死亡对象占较小部分,因此清除阶段所占用的时间也比较少。

    Mark-Sweep存在的问题是只清除而不整理,这样会导致内存空间出现不连续的状态,这不利于分配内存给大对象。

    为了解决这一问题,Mark-Compact出现了。他们的差别在于第二阶段,Mark-Compact是将活着的对象都往左侧移动,全部移动完成后再一次性清理掉边界右侧的无效内存空间。这样就可以得到完整连续的可用内存空间。

    但Mark-Compact也不是十全十美的,它的缺点在于移动大量的存活对象会消耗比较多的时间。所以 v8 引擎在实际使用中会根据具体情况选择使用Mark-Sweep或者Mark-Compact。

    三种算法对比:

    理解 NodeJS 的内存管理机制

    停顿优化

    由于程序在执行运算时会不断地生成新对象,因此垃圾回收进行时必须要将应用暂停下来。

    在分代式垃圾回收机制下,新生代的垃圾回收过程比较快,因此可以直接将程序暂停下来进行回收,然后再恢复程序运行。

    而对于老生代的垃圾回收来说,全程停顿造成的暂停时间较长,会影响程序的执行性能,因此 v8 引擎会标记阶段和清理阶段改为增量方式执行。也就是说将某个阶段拆分为几个小步骤,每执行完一步后就恢复程序执行,将垃圾回收工作穿插在程序执行的间隙中。


    起源地下载网 » 理解 NodeJS 的内存管理机制

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元