【问题标题】:NodeJs - near heap limit Allocation failed - JavaScript heap out of memoryNodeJs - 接近堆限制分配失败 - JavaScript堆内存不足
【发布时间】:2020-03-20 08:12:13
【问题描述】:

我有一个节点 js 应用程序,在 AWS EC2 作为 m5xlarge 实例和 ubuntu 18.04 操作系统中运行,它有一个 main.js 文件,在主文件中我使用 node-cron 来安排多个 cron 作业,一次作业计划使用另一个文件app.js 启动应用程序,间歇性地我面临内存不足错误并且服务器停止日志如下所示 -

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: node::Abort() [node /home/ubuntu/XXXXXX/main.js]
 2: 0x89371c [node /home/ubuntu/XXXXXX/main.js]
 3: v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node /home/ubuntu/XXXXXX/main.js]
 4: v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node /home/ubuntu/XXXXXX/main.js]
 5: 0xe617e2 [node /home/ubuntu/XXXXXX/main.js]
 6: v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node /home/ubuntu/XXXXXX/main.js]
 7: v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node /home/ubuntu/XXXXXX/main.js]
 8: v8::internal::Heap::AllocateRawWithRetry(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node /home/ubuntu/XXXXXX/main.js]
 9: v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationSpace) [node /home/ubuntu/XXXXXX/main.js]
10: v8::internal::Runtime_AllocateInNewSpace(int, v8::internal::Object**, v8::internal::Isolate*) [node /home/ubuntu/XXXXXX/main.js]
11: 0x2a583f5041bd

内存利用率和健康检查监视器如下-

峰值是由于 cron 作业按时间间隔运行,最高的是每小时 cron 作业。

现在我的假设是它可能是由于任何 cron 作业失败导致 main.js 中的内存不足错误,因此 app.js 中的应用程序也停止,或者应用程序本身在 app.js cron 作业调度中失败如下所示 -

const cluster = require('cluster');
const numCPUs = 1 //require('os').cpus().length;
var CronJob = require('cron').CronJob;
const spawn = require('child_process').spawn;
require('dotenv').config()

if (cluster.isMaster) {
   if (process.env.kEnvironment == "dev") {
        var sampleCron = new CronJob('00 */10 * * * *', function () {
            spawn(process.execPath, ['./sampleCron.js'], {
                stdio: 'inherit'
            })
        }, null, true, null);
    } else {
        var sampleCron = new CronJob('00 15 10 * * 0', function () {
            spawn(process.execPath, ['./sampleCron.js'], {
                stdio: 'inherit'
            })
        }, null, true, null);
    }
    // There are multiple cron like the above

    for (let i = 0; i < numCPUs; i++) {
        cluster.fork();
    }

    cluster.on('exit', (worker, code, signal) => {
        console.log(`worker ${worker.process.pid} died`);
    });

} else {
    require('./app.js');
}

这是一个关于这个的 htop 预览 -

这里有几个问题 - - 为什么在 main.js 中显示 main.js 树,这种嵌套正常吗? - 如果相同,为什么两者的资源内存利用率不同?

我尝试如下增加每个 cron 的内存 -

  var sampleCron = new CronJob('00 15 10 * * 0', function () {
            spawn(process.execPath, ['./sampleCron.js','--max-old-space-size=4096'], {
                stdio: 'inherit'
            })
        }, null, true, null);

但它仍然失败。我的问题如下-

  • 我如何隔离问题,究竟是由于 crons 还是由于应用程序造成的。
  • 我该如何解决这个问题?

【问题讨论】:

  • 在我的直觉中,它主要在代码中,你需要对它进行基准测试、测试、分析它,因为所有 cron 所做的就是在特定时间、特定时期执行特定任务。跨度>
  • 我同意,这可能是由于代码。但是提供足够的资源服务器应该不会崩溃,对吧? m5xlarge 是 32 Gigs 内存和 4 核处理器,在我看来应该能够处理任何事情。虽然代码需要优化,但作为一个即时修复,解决方案可能是什么?
  • 开始一一删除 cron 作业,你会找到罪魁祸首,或者最好做一个 top / htop,你会看到哪个进程在飙升
  • 这就是你看到的问题,这一切都是从 main.js 开始的,htop 只怪 main.js 使用了 1.8% 的内存。由于它是生产应用程序,因此删除 cron 作业也是不可能的。
  • 在本地对代码进行剖析以查看代码是否被正确剖析以及隐藏的警告是什么

标签: node.js ubuntu amazon-ec2 cron


【解决方案1】:

使用诸如“Top”之类的命令来找出节点进程正在使用多少内存。我认为节点脚本不会使用所有可用内存。您也可以尝试使用 NODE_OPTIONS 分配更多内存。 例如节点 SomeScript.js --max-old-space-size=8192

【讨论】:

  • 如果您仔细阅读问题,上述步骤已经到位。
  • 你试过给main.js文件分配内存吗?
  • 是的 main 已经使用export NODE_OPTIONS=--max_old_space_size=4096分配了内存
猜你喜欢
  • 2021-05-06
  • 2021-10-20
  • 2018-09-29
  • 2020-08-22
  • 2023-03-18
  • 2020-06-25
  • 2023-01-13
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多