Node.js堆内存不足

时间:2016-07-25 02:45:22

标签: javascript node.js crash out-of-memory heap-memory

今天我运行文件系统索引的脚本来刷新RAID文件索引,4小时后崩溃并出现以下错误:

[md5:]  241613/241627 97.5%  
[md5:]  241614/241627 97.5%  
[md5:]  241625/241627 98.1%
Creating missing list... (79570 files missing)
Creating new files list... (241627 new files)

<--- Last few GCs --->

11629672 ms: Mark-sweep 1174.6 (1426.5) -> 1172.4 (1418.3) MB, 659.9 / 0 ms [allocation failure] [GC in old space requested].
11630371 ms: Mark-sweep 1172.4 (1418.3) -> 1172.4 (1411.3) MB, 698.9 / 0 ms [allocation failure] [GC in old space requested].
11631105 ms: Mark-sweep 1172.4 (1411.3) -> 1172.4 (1389.3) MB, 733.5 / 0 ms [last resort gc].
11631778 ms: Mark-sweep 1172.4 (1389.3) -> 1172.4 (1368.3) MB, 673.6 / 0 ms [last resort gc].


<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x3d1d329c9e59 <JS Object>
1: SparseJoinWithSeparatorJS(aka SparseJoinWithSeparatorJS) [native array.js:~84] [pc=0x3629ef689ad0] (this=0x3d1d32904189 <undefined>,w=0x2b690ce91071 <JS Array[241627]>,L=241627,M=0x3d1d329b4a11 <JS Function ConvertToString (SharedFunctionInfo 0x3d1d3294ef79)>,N=0x7c953bf4d49 <String[4]\: ,\n  >)
2: Join(aka Join) [native array.js:143] [pc=0x3629ef616696] (this=0x3d1d32904189 <undefin...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/usr/bin/node]
 2: 0xe2c5fc [/usr/bin/node]
 3: v8::Utils::ReportApiFailure(char const*, char const*) [/usr/bin/node]
 4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [/usr/bin/node]
 5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [/usr/bin/node]
 6: v8::internal::Runtime_SparseJoinWithSeparator(int, v8::internal::Object**, v8::internal::Isolate*) [/usr/bin/node]
 7: 0x3629ef50961b

服务器配备16GB RAM和24GB SSD交换。我非常怀疑我的脚本超过36GB的内存。至少它不应该

脚本创建存储为具有文件元数据的对象数组的文件索引(修改日期,权限等,无大数据)

这是完整的脚本代码: http://pastebin.com/mjaD76c3

我已经在过去用这个脚本经历了奇怪的节点问题,这迫使我如此。将索引拆分成多个文件,因为当处理像String这样的大文件时,节点会出现故障。有没有办法用庞大的数据集改进nodejs内存管理?

34 个答案:

答案 0 :(得分:195)

如果我没记错的话,如果不手动增加,则V8中的内存使用量有一个严格的标准限制,大约为1.7 GB。

在我们的某个产品中,我们在部署脚本中使用了此解决方案:

 node --max-old-space-size=4096 yourFile.js

还会有一个新的空间命令,但正如我在此处所读到的:a-tour-of-v8-garbage-collection新空间仅收集新创建的短期数据,旧空间包含所有引用的数据结构,在您的情况下应该是最佳选择。

答案 1 :(得分:23)

以防万一有人在无法直接设置节点属性(在我的情况下是构建工具)的环境中遇到此问题:

NODE_OPTIONS="--max-old-space-size=4096" node ...

如果无法在命令行上传递节点选项,则可以使用环境变量来设置它们。

答案 2 :(得分:21)

我在尝试使用VSCode进行调试时遇到了这个问题,所以只想添加这个就是如何将参数添加到调试设置中。

您可以将其添加到launch.json中配置的{ "version": "0.2.0", "configurations": [{ "type": "node", "request": "launch", "name": "Launch Program", "program": "${workspaceRoot}\\server.js" }, { "type": "node", "request": "launch", "name": "Launch Training Script", "program": "${workspaceRoot}\\training-script.js", "runtimeArgs": [ "--max-old-space-size=4096" ] } ]} 属性中。

见下面的例子。

function GetFoodDetails() {
  $.get('/Home/GetDefects', null, function (data) {
        $.each(data.dataList, function (i, dl) {
            alert(dl.ID);
        });
    });

}

答案 3 :(得分:17)

如果要全局增加节点的内存使用量-不仅是单个脚本,还可以导出环境变量,如下所示:
<script> function initMap() { gMap = new google.maps.Map(document.getElementById('map')); navigator.geolocation.getCurrentPosition(function(position) { // Center on user's current location if geolocation prompt allowed var initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); gMap.setCenter(initialLocation); gMap.setZoom(13); }, function(positionError) { // User denied geolocation prompt - default to Chicago gMap.setCenter(new google.maps.LatLng(39.8097343, -98.5556199)); gMap.setZoom(5); }); } </script>

然后,当您运行诸如以下版本的构建时,无需播放文件 export NODE_OPTIONS=--max_old_space_size=4096

答案 4 :(得分:15)

我的EC2实例t2.micro遇到了同样的问题,它具有1 GB的内存。

我通过使用this网址创建交换文件并设置了以下环境变量来解决了该问题。

app

最后问题解决了。

我希望这对将来会有所帮助。

答案 5 :(得分:12)

即使设置了--max-old-space-size,我也在努力解决这个问题。

然后我意识到需要在业力剧本之前添加选项--max-old-space-size。

最好同时指定语法--max-old-space-size和--max_old_space_size我的karma脚本:

node --max-old-space-size=8192 --optimize-for-size --max-executable-size=8192  --max_old_space_size=8192 --optimize_for_size --max_executable_size=8192 node_modules/karma/bin/karma start --single-run --max_new_space_size=8192   --prod --aot

参考https://github.com/angular/angular-cli/issues/1652

答案 6 :(得分:9)

fwiw,找到并修复类似memwatch之类的记忆猪可能有所帮助。

答案 7 :(得分:7)

我只想在某些系统中添加它,甚至使用--max-old-space-size来增加节点内存限制,这还不够,并且会出现如下操作系统错误:

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

在这种情况下,可能是因为您达到了每个进程的最大mmap。

您可以通过运行来检查max_map_count

sysctl vm.max_map_count

并通过运行增加它

sysctl -w vm.max_map_count=655300

并通过添加以下代码行将其修复,以使其在重启后不被重置

vm.max_map_count=655300

/etc/sysctl.conf文件中。

检查here以获得更多信息。

一种分析错误的好方法是使用strace

运行该过程
strace node --max-old-space-size=128000 my_memory_consuming_process.js

答案 8 :(得分:7)

有些标志值可在启动节点服务器时添加一些有关如何允许更多内存的附加信息。

1GB-8GB

#increase to 1gb
node --max-old-space-size=1024 index.js

#increase to 2gb
node --max-old-space-size=2048 index.js 

#increase to 3gb
node --max-old-space-size=3072 index.js

#increase to 4gb
node --max-old-space-size=4096 index.js

#increase to 5gb
node --max-old-space-size=5120 index.js

#increase to 6gb
node --max-old-space-size=6144 index.js

#increase to 7gb
node --max-old-space-size=7168 index.js

#increase to 8gb 
node --max-old-space-size=8192 index.js 

答案 9 :(得分:7)

在进行AOT角度构建时,我遇到了类似的问题。遵循命令可以帮助我。

npm install -g increase-memory-limit
increase-memory-limit

来源:https://geeklearning.io/angular-aot-webpack-memory-trick/

答案 10 :(得分:6)

  

修复步骤-

  1. 打开命令提示符,然后输入bitmap.setPixel(20, 20, Color.WHITE); 并按Enter
  2. 导航到10-19 07:27:23.522 25370-25483/org.anthe.robocup11 E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb9af65e8 10-19 07:27:24.430 25370-25549/org.anthe.robocup11 E/AndroidRuntime: FATAL EXCEPTION: pool-4-thread-1 Process: org.anthe.robocup11, PID: 25370 java.lang.IllegalStateException at android.graphics.Bitmap.setPixel(Bitmap.java:1490) at org.anthe.robocup11.MainActivity$SampleFrameProcessor$override.process(MainActivity.java:111) at org.anthe.robocup11.MainActivity$SampleFrameProcessor$override.access$dispatch(MainActivity.java) at org.anthe.robocup11.MainActivity$SampleFrameProcessor.process(MainActivity.java) at io.fotoapparat.FotoapparatBuilder$frameProcessor$2$1$1.invoke(FotoapparatBuilder.kt:137) at io.fotoapparat.FotoapparatBuilder$frameProcessor$2$1$1.invoke(FotoapparatBuilder.kt:21) at io.fotoapparat.preview.PreviewStream.dispatchFrame(PreviewStream.kt:107) at io.fotoapparat.preview.PreviewStream.access$dispatchFrame(PreviewStream.kt:16) at io.fotoapparat.preview.PreviewStream$dispatchFrameOnBackgroundThread$1.run(PreviewStream.kt:92) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) at java.lang.Thread.run(Thread.java:818) 10-19 07:27:24.640 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.646 25370-25483/org.anthe.robocup11 E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb9be56c0 10-19 07:27:24.668 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.669 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.709 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.711 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.749 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.750 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.791 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.792 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.830 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.831 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.872 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.874 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.909 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] queueBuffer: BufferQueue has been abandoned 10-19 07:27:24.912 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] dequeueBuffer: BufferQueue has been abandoned 10-19 07:27:24.961 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.962 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.962 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.962 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.962 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.963 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.963 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.963 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.964 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.964 25370-25382/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.964 25370-25381/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned 10-19 07:27:24.964 25370-25538/org.anthe.robocup11 E/BufferQueueProducer: [SurfaceTexture-0-25370-1] cancelBuffer: BufferQueue has been abandoned > npm文件夹
  3. 在您喜欢的编辑器中打开或编辑%appdata%
  4. 在IF和ELSE块中添加%appdata%

更改后,您的ng.cmd文件如下所示:

--max_old_space_size=8192

答案 11 :(得分:4)

可以使用以下环境变量:

NODE_OPTIONS= --max-old-space-size=8192 .

另一个说明:console.log()还会占用终端中的内存。

只是试图在终端上注释console.log()。因为那也会占用内存。

答案 12 :(得分:3)

最近,在我的一个项目中遇到了同样的问题。尝试了一些任何人都可以尝试的调试方法来确定根本原因:

  1. 正如大家所建议的,通过添加以下命令来增加节点中的内存限制:

    {
       "scripts":{
          "server":"node --max-old-space-size={size-value} server/index.js"
       }
    }
    

这里 size-value 我为我的应用程序定义的是 1536(因为我的 kubernetes pod 内存是 2 GB 限制,请求 1.5 GB)

因此始终根据您的前端基础架构/架构限制(略小于限制)定义 size-value

上述命令中的一个严格标注,在 --max-old-space-size 命令之后使用 node,而不是在文件名 server/index.js 之后。

  1. 如果您有 ngnix 配置文件,请检查以下内容:

    • worker_connections:16384(用于繁重的前端应用程序) [nginx 默认为每个 512 的连接数为 worker,这对于现代应用来说太低了]

    • 使用:epoll(高效方法)【nginx支持多种连接处理方法】

    • http:添加以下内容,让您的工作人员免于忙于处理一些不需要的任务。 (client_body_timeout、reset_timeout_connection、client_header_timeout、keepalive_timeout、send_timeout)。

  2. 删除所有日志记录/跟踪工具,例如 APM , Kafka , UTM tracking, Prerender (SEO) 等中间件或关闭。

  3. 现在代码级调试:在您的主 server 文件中,删除不需要的 console.log,它只是打印一条消息。

  4. 现在检查每个服务器路由,即以下场景中的 app.get() , app.post() ...

  • data => if(data) res.send(data) // 你真的需要等待数据还是 api 返回一些我必须等待的响应? , 如果没有,则像这样修改:
data => res.send(data) // this will not block your thread, apply everywhere where it's needed
  • else 部分:如果没有出现错误,则只需 return res.send({})NO console.log here

  • 错误部分:有些人将其定义为 errorerr,这会造成混淆和错误。像这样:

    `error => { next(err) } // here err is undefined`
    
     `err => {next(error) } // here error is undefined`
    
     `app.get(API , (re,res) =>{
         error => next(error) // here next is not defined
      })`
    
  • 使用 winston 命令删除 elastic-epm-nodenpx depcheck 其他未使用的库。

  • 在 axios 服务文件中,检查方法和日志是否正确,例如:

      if(successCB) console.log("success") successCB(response.data) // here it's wrong statement, because on success you are just logging and then `successCB` sending  outside the if block which return in failure case also.
    
  • 避免在可访问的大型数据集上使用 stringify , parse 等。 (我也可以在上面显示的日志中看到。

  1. 最后但并非最不重要的一点是,每次当您的应用程序崩溃或 Pod 重新启动时,请检查日志。在日志中专门查找此部分:Security context 这将告诉您为什么、在哪里以及谁是崩溃背后的罪魁祸首

答案 13 :(得分:2)

就我而言,我将node.js版本升级到了最新版本(12.8.0版),它的工作原理很吸引人。

答案 14 :(得分:2)

我最近也遇到了同样的问题,遇到了这个线程,但是我的问题是React应用。下面的node start命令更改解决了我的问题。

语法

node --max-old-space-size=<size> path-to/fileName.js

示例

node --max-old-space-size=16000 scripts/build.js

为什么最大空间大小为16000?

基本上,它取决于该线程分配的内存和您的节点设置。

如何验证尺寸并提供合适的尺寸?

这基本上留在我们的引擎v8中。以下代码可帮助您了解本地节点v8引擎的堆大小。

const v8 = require('v8');
const totalHeapSize = v8.getHeapStatistics().total_available_size;
const totalHeapSizeGb = (totalHeapSize / 1024 / 1024 / 1024).toFixed(2);
console.log('totalHeapSizeGb: ', totalHeapSizeGb);

答案 15 :(得分:1)

对于Angular,我是这样修复的

Package.json 中,在 script 标签内添加这个

"scripts": {
  "build-prod": "node --max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng build --prod",
},

现在在 terminal/cmd 而不是使用 ng build --prod 只是使用

npm run build-prod

如果您只想对 build 使用此配置,只需从所有 3 个位置中删除 --prod

答案 16 :(得分:1)

对于像我这样的其他初学者,他们没有找到适合该错误的解决方案,请检查已安装的节点版本(x32,x64,x86)。我有一个64位CPU,并且已经安装了x86节点版本,这导致了CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory错误。

答案 17 :(得分:1)

使用选项 --optimize-for-size。它将专注于使用更少的内存。

答案 18 :(得分:1)

此命令完美运行。我的笔记本电脑中有8GB内存,因此我将大小设置为8192。都是关于ram的,而且您还需要设置文件名。我运行 npm run build 命令,这就是为什么我使用 build.js 的原因。

node --expose-gc --max-old-space-size=8192 node_modules/react-scripts/scripts/build.js

答案 19 :(得分:1)

如果要全局更改节点(Windows)的内存,请转至高级系统设置->环境变量->新用户变量

variable name = NODE_OPTIONS
variable value = --max-old-space-size=4096

答案 20 :(得分:1)

对于有角度的项目捆绑,我已经脚本部分的 pakage.json 文件中添加了以下行。

"build-prod": "node --max_old_space_size=5120 ./node_modules/@angular/cli/bin/ng build --prod --base-href /"

现在,要捆绑我的代码,我使用npm run build-prod而不是ng build --requiredFlagsHere

希望这会有所帮助!

答案 21 :(得分:1)

我尝试了下面的代码及其正常工作✌。

  • 从项目根目录打开终端
  • 执行cmd以设置新大小。

    set NODE_OPTIONS =-max_old_space_size = 8172

或者您可以查看链接以获取更多信息 https://github.com/nodejs/node/issues/10137#issuecomment-487255987

答案 22 :(得分:1)

为了防止人们在使用产生大量日志记录的nodejs应用程序时遇到此问题,同事通过将标准输出传递给文件解决了这个问题。

答案 23 :(得分:1)

将节点升级到最新版本。我在节点6.6上遇到此错误并升级到8.9.4并且问题消失了。

答案 24 :(得分:0)

如果您尝试启动的不是node本身,而是其他一些软件,例如webpack,则可以使用环境变量和cross-env软件包:

$ cross-env NODE_OPTIONS='--max-old-space-size=4096' \
  webpack --progress --config build/webpack.config.dev.js

答案 25 :(得分:0)

就我而言,我在旧版本的节点上运行过npm install,一天后,我升级了节点版本,并为几个模块升级了npm install内存。之后,我得到了这个错误。 为了解决此问题,我从每个项目中删除了node_module文件夹,然后再次运行npm install

希望这可以解决问题。

注意:这是在我的本地计算机上发生的,并且仅在本地计算机上已解决。

答案 26 :(得分:0)

您还可以使用以下方法更改Window的环境变量:

 $env:NODE_OPTIONS="--max-old-space-size=8192"

答案 27 :(得分:0)

它很简单,只需将堆内存从1-8 GB增加 对于Windows,请在您的项目目录中打开powershell或cmd,然后在命令下方键入, 对于该目录中的mac open终端

node --max-old-space-size={size in MBs} index.js

答案 28 :(得分:0)

如果任何给定的答案对您不起作用,请检查您安装的节点是否与您的系统兼容(即 32 位或 64 位)。通常这种类型的错误是因为节点和操作系统版本不兼容而发生的,终端/系统不会告诉你这一点,但会让你给出内存不足的错误。

答案 29 :(得分:0)

如果您的内存或 RAM 有限,请执行以下命令。

<块引用>

ng serve --source-map=false

它将能够启动应用程序。对于我的示例,它需要 16GB RAM。但我可以用 8GB RAM 运行。

答案 30 :(得分:0)

运行这个命令 ng build --configuration

答案 31 :(得分:0)

检查您没有在 64 位机器上安装 32 位版本的 node。如果您在 64 位或 32 位机器上运行 node,则 nodejs 文件夹应分别位于 Program Files 和 Program Files (x86) 中。

答案 32 :(得分:0)

我会提到两种解决方案。

我的解决方案:就我而言,我将其添加到我的环境变量中:

export NODE_OPTIONS=--max_old_space_size=20480

但是即使我重新启动计算机,它仍然无法正常工作。我的项目文件夹在 d:\ 磁盘中。所以我将我的项目删除到 c:\ 磁盘并且它工作了。

我的队友的解决方案:package.json 配置也有效。

"start": "rimraf ./build && react-scripts --expose-gc --max_old_space_size=4096 start",

答案 33 :(得分:-2)

在 tsconfig.我将目标 :"es05" 更改为目标 :"es2020" 的 Json 文件 它对我有用。