node内存限制
node在运行时,内存是有限制的,据说
- 32位系统内存限制0.7G
- 64位系统内存限制1.4G
一旦运行内存超过上述限制,就会出现堆栈溢出的报错。针对这个问题,网上已经有非常丰富的解决方案。笔者并不想讨论这些解决方案的优缺点,不过想借这篇文章介绍一下,此问题的终极解决方案,也是放之四海而皆准的解决方案。
方案关键与原理
node本身提供了一种扩大运行内存的方案,这也是所有解决方案,包括本篇文章所提供方案的根基与关键,那就是在node运行时,带上扩大内存的参数。以下是官方文档的描述。
V8 has its own set of CLI options. Any V8 CLI option that is provided to node will be passed on to V8 to handle. V8’s options have no stability guarantee. The V8 team themselves don’t consider them to be part of their formal API, and reserve the right to change them at any time. Likewise, they are not covered by the Node.js stability guarantees. Many of the V8 options are of interest only to V8 developers. Despite this, there is a small set of V8 options that are widely applicable to Node.js, and they are documented here:
–max-old-space-size=SIZE (in megabytes)#
Sets the max memory size of V8’s old memory section. As memory consumption approaches the limit, V8 will spend more time on garbage collection in an effort to free unused memory.On a machine with 2 GiB of memory, consider setting this to 1536 (1.5 GiB) to leave some memory for other uses and avoid swapping.
$ node --max-old-space-size=1536 index.js
–max-old-space-size=SIZE 参数能控设置V8运行的最大内存(单位:MB),这就是本方案的基本原理。
具体方案
接下来就是本文章要重磅介绍的方案了,那就是
node --max-old-space-size=8192 xxx/xxx/xxx.js
看到这里的读者可能就要开喷了,这方案跟别的方案有什么不一样吗,换汤不换药啊。其实如果说只是运行自写的js文件,看到这里基本都够用了。然而在我们的实际应用中,我们往往需要调用其他命令, 比如利用子进程调用tsc命令编译项目,这时候如果只是单纯采用此方式运行自己写的js文件,仍然会堆栈内存溢出。因此我们需要将其他nodejs命令修改这样的形式,比如tsc命令改写为调用node --max-old-space-size=8192 xxx/xxx/tsc.js
这样的形式。所以重点就是如何确定xxx/xxx/tsc.js
这部分。
分析nodejs命令写法
我们以安装typescript包后,生成的tsc.cmd为例来加以分析。tsc.cmd本身是一个批处理文件,用普通文本编辑软件即可打开,打开内容如下
@ECHO off
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
"%_prog%" "%dp0%\node_modules\typescript\bin\tsc" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b
关键地方是第12行, "%_prog%“实际上就是node,”%dp0%\node_modules\typescript\bin\tsc"就是运行的js文件。也就是说tsc.cmd命令执行时,实际上就是使用node执行了node_modules\typescript\bin\tsc这个文件。因此如果我们要在child_process内调用tsc命令时,只需要将tsc命令替换为
node --max-old-space-size=8192 (相对或绝对路径)node_modules/typescript/bin/tsc
即可。任何npm包安装的命令都可以才用这种方式去处理,以解决堆栈内存溢出的问题。
总结
以上就是本篇文章介绍的内存堆栈溢出的终极解决方案,能够应对任何情况下调用node堆栈内存溢出的问题,同时提供了一种直接查找node命令运行的js文件的方式,希望对读者朋友们有帮助。当然这些对老鸟来说都是小case,可以完全跳过。