背景介绍

公司一个ReactOnRails的项目,之前一直都是跑的好好的。上次一个小修改后,发布预编译React代码的时候,屡次出现FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory 的错误。

调查

项目使用的是webpacker打包js代码,一开始是以为webpacker的问题,调查了一圈下来,最终发现是node中V8的限制。默认情况下,在64位系统下内存使用是有限制的,有一说是1.4GB,有一说是1.76GB。但在node官网搜了一圈也没找到明确说现在的限制是多少。

在预编译的报错信息中,找到了如下的错误信息,应该是超过了默认的使用限额,使得node进程爆掉了。

1
2
3
4
5
6
<--- Last few GCs --->
155958 ms: Mark-sweep 1225.9 (1439.4) -> 1225.9 (1439.4) MB, 1078.8 / 0.0 ms [allocation failure] [GC in old space requested].
157041 ms: Mark-sweep 1225.9 (1439.4) -> 1225.9 (1439.4) MB, 1082.3 / 0.0 ms [allocation failure] [GC in old space requested].
158129 ms: Mark-sweep 1225.9 (1439.4) -> 1235.9 (1423.4) MB, 1087.9 / 0.0 ms [last resort gc].
159213 ms: Mark-sweep 1235.9 (1423.4) -> 1246.1 (1423.4) MB, 1083.6 / 0.0 ms [last resort gc].

最终的解决方案是,在使用node之前,设置环境变量NODE_OPTIONS=--max_old_space_size为一个更大的值,此处,设置NODE_OPTIONS=--max_old_space_size=4096后,解决了问题。

注意的是,破折号格式的NODE_OPTIONS=--max-old-space-size似乎是不起作用的。

任何可以使用环境变量来修改配置的软件,都是部署友好的软件, 特别的适用于类似Elastic Beanstalk这种集成的发布环境。

Reference

留言