点击上方“筑梦前端”欢迎订阅
使用JavaScript进行前端开发时几乎完全不需要关心内存管理问题,对于前端编程来说,V8限制的内存几乎不会出现用完的情况,但是由于后端程序往往进行的操作更加复杂,并且长期运行在服务器不重启,如果不关注内存管理,导致内存泄漏,就算1TB,也会很快用尽。
Node.js构建于V8引擎之上,因此本文首先讲解V8引擎的内存管理机制,了解底层原理后,再讲解Node开发中的内存管理与优化。
一、V8的内存管理机制
1.1 内存管理模型
Node程序运行中,此进程占用的所有内存称为常驻内存(Resident Set)。
常驻内存由以下部分组成:
代码区(Code Segment):存放即将执行的代码片段
栈(Stack):存放局部变量
堆(Heap):存放对象、闭包上下文
堆外内存:不通过V8分配,也不受V8管理。Buffer对象的数据就存放于此。
除堆外内存,其余部分均由V8管理。
栈(Stack)的分配与回收非常直接,当程序离开某作用域后,其栈指针下移(回退),整个作用域的局部变量都会出栈,内存收回。
最复杂的部分是堆(Heap)的管理,V8使用垃圾回收机制进行堆的内存管理,也是开发中可能造成内存泄漏的部分,是程序员的关注点,也是本文的探讨点。
通过process.memoryUsage()
可以查看此Node进程的内存使用状况:
rss
是Resident Set Size的缩写,为常驻内存的总大小,heapTotal
是V8为堆分配的总大小,heapUsed
是已使用的堆大小。可以看到,rss是大于heapTotal的,因为rss包括且不限于堆。
1.2 堆内存限制
默认情况下,V8为堆分配的内存不超过1.4G:64位系统1.4G,32位则仅分配0.7G。也就是说,如果你想使用Node程序读一个2G的文件到内存,在默认的V8配置下,是无法实现的。不过我们可以通过Node的启动命令更改V8为堆设置的内存上限:
//更改老年代堆内存
--max-old-space-size=3000 // 单位为MB// 更改新生代堆内存
--max-new-space-size=1024 // 单位为KB
堆的内存上限在启动时就已经决定,无法动态更改,想要更改,唯一的方法是关闭进程,使用新的配置重新启动。</