之前上线的一个基于next.js的服务端渲染项目在生产环境访问突然出现 503错误,起初还以为是Nginx配置除了问题,随后看pm2日志发现了这么一条报错信息:
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed – JavaScript heap out of memory
由于之前没有遇到过此类问题,但看字面意思可以发现是JS内存溢出了。随后便查找资料找到了一些线索。
原来NodeJS中通过JavaScript只能使用部分内存(64位约1.4G,32位约0.7G),这是源自于V8引擎对内存做了限制,所以当网站访问量大了后消耗的内存也有可能会突破这这一限制,从而导致会出现内存溢出的错误。
如何突破限制:
一、可以通过设置环境变量,node启动时会读取该环境变量,设置完后需要重启node服务。
// 值可以根据项目情况修改,注意该参数的值为数值,不需要带单位 export NODE_OPTIONS="--max-old-space-size=4096"
如需验证是否生效,可以进入node运行环境,输入如以下代码查看设置后的值是否生效。
`node heap limit = ${require('v8').getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`
二、如果是基于pm2管理的node项目可以在pm2配置中加上如下配置,设置完后需要重新运行 pm2 start
命令启动项目。
module.exports = { apps: [ { name: 'my-app', node_args: ['--max_old_space_size=4096'], // 这一条配置 }, ], };
设置完成后可以输入pm2 monit
命令,进入可视化视图查看设置是否生效。
为什么V8要对内存使用做限制?
V8是为浏览器而设计的,前期足以满足浏览器端的需求;深层原因是V8的垃圾回收机制,垃圾回收耗时,引起JavaScript线程暂停执行时间。