盒子
盒子
文章目录
  1. 内存限制
  2. V8的垃圾回收机制
    1. 新生代
    2. 老生代
      1. 晋升
      2. 算法
      3. 全停顿(stop-the-world)
    3. 无法立即回收的内存
  3. 堆外内存

Node.js的内存控制

内存限制

Node基于V8构建,所以存在一定的内存限制(64位系统下约为1.4GB, 32位系统下约为0.7GB)
可用process.memoryUsage()查看
在启动node时可以通过传递
--max-old-space-size--max-new-space-size更改,前者对应单位MB,用于更改老生代内存,后者对应单位KB,用于更改新生代内存

V8的垃圾回收机制

V8中内存分为新生代(存活时间较短的对象)和老生代(存活时间较长的对象)

新生代

Scavenge算法(主要采用了Cheney算法)

  • 将堆内存一分为二,每一部分空间叫semispace,使用中的叫From,闲置的叫To
  • 开始垃圾回收时,先检查From中的存活,将其复制到To,其余释放,完成后From与To二者交换(这个交换的过程也称翻转)
  • 是一种典型的牺牲空间换取时间的算法,但是非常适合新生代这种场合

老生代

晋升

若一个对象经过多次复制依然存活时,会被移动到老生代中,称为晋升
晋升的要求:(将对象从From到To时):

  • 若对象经历过一次Scavenge回收,则复制到老生代空间里
  • 若To中空间使用大于25%,则复制到老生代空间里

算法

老生代垃圾回收的算法:

  • mark-sweep算法:字面上理解,第一步,标记;第二步,清除。标记活着的对象,只清理死亡的对象。缺点,会存在碎片空间。
  • mark-compact算法:第一步,标记死亡对象;第二步,整理,将活着的对象往一端移动,移动完成后,直接清理掉边界外的内存。

主要使用mark-sweep:因为速度快

全停顿(stop-the-world)

在进行垃圾回收的时候会全停顿,而在老生代中全停顿时间很久,所以有增量标记

无法立即回收的内存

  • 全局变量
  • 闭包

堆外内存

Node中的内存使用并非都是通过V8进行分配的,不是通过V8分配的内存称为堆外内存

  • Buffer使用的是堆外内存,没有堆内存的大小限制