wax5798 2022-01-25 11:21 采纳率: 90.9%
浏览 117
已结题

nodejs 使用 express 传输大文件(140M 左右)时崩溃(出现 GC 异常)

环境说明

嵌入式设备,搭建的是 ubuntu 系统
nodejs 版本 v12.18.0

问题遇到的现象和发生背景

在我的一个嵌入式设备中,需要使用 nodejs + express 传输文件,文件大小为 140M 左右,结果导致 nodejs 崩溃,打印异常信息如下

<--- Last few GCs --->

[1767:0x1fb9640]    50630 ms: Mark-sweep 284.2 (289.3) -> 284.1 (285.8) MB, 119.6 / 0.0 ms  (average mu = 0.944, current mu = 0.003) last resort GC in old space requested
[1767:0x1fb9640]    50700 ms: Mark-sweep 284.1 (285.8) -> 284.1 (285.8) MB, 69.7 / 0.0 ms  (average mu = 0.910, current mu = 0.001) last resort GC in old space requested


<--- JS stacktrace --->

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

Security context: 0x42da58b9 <JSObject>
    0: builtin exit frame: byteLength(aka byteLengthUtf8)(this=0x3f764a79 <Object map = 0x2ecd615d>,0x3ae30491 <Very long string[147123807]>,0x3f764a79 <Object map = 0x2ecd615d>)

    1: fromStringFast(aka fromStringFast) [0x3f7630b1] [buffer.js:424] [bytecode=0x3f77fe35 offset=7](this=0x495c0279 <undefined>,0x3ae30491 <Very long string[147123807]>,0x3f764a79 <Object map = 0x2ecd615d>)
    2: fromSt...

相关代码简化之后如下

let getSystemLog = function(req, res) {
  let content = '';

  if (fs.existsSync(system_log_file1)) {
    content += "\n>>>>>>>>>>" + system_log_file1 + "<<<<<<<<<<\n" + fs.readFileSync(system_log_file1);
  }

  if (fs.existsSync(system_log_file2)) {
    content += "\n>>>>>>>>>>" + system_log_file2 + "<<<<<<<<<<\n" + fs.readFileSync(system_log_file2);
  }

  res.send(content);
};

针对这个问题,自己查过一些资料,了解 nodejs 的大致 GC 机制,以及 nodejs v8 的堆栈限制。初步怀疑是 nodejs 堆栈限制导致的问题

我的解答思路和尝试过的方法

我有尝试过压缩之后再传输,然而由于嵌入式资源有限,压缩时间太长(需要十多分钟),所以这种方法并不实用

我想要达到的结果

所以能否有朋友帮忙解答如下问题:
1、怎么查看和设置当前 nodejs 的堆栈大小
2、对于大文件传输,有没有其他更高效的方式

不胜感激

  • 写回答

4条回答 默认 最新

  • Daniel Tan 2022-01-25 12:21
    关注

    这个为什么不考虑streaming方式传输呢

    估计你把res.send换成res.write(就是要用buffer之类的分块) 最后加一个res.end 就没事了,在接收那里也处理streaming chunks 就可以了但是不处理通常也会自动处理的

    function(req, res, next) {
      if(req.url==="somethingorAnother") {
        res.setHeader("content-type", "some/type");
        fs.createReadStream("./toSomeFile").pipe(res);
      } else {
        next(); // not our concern, pass along to next middleware function
      }
    }
    

    这样也可以。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(3条)

报告相同问题?

问题事件

  • 系统已结题 2月2日
  • 已采纳回答 1月25日
  • 创建了问题 1月25日

悬赏问题

  • ¥15 r语言神经网络自变量重要性分析
  • ¥15 基于双目测规则物体尺寸
  • ¥15 wegame打不开英雄联盟
  • ¥15 公司的电脑,win10系统自带远程协助,访问家里个人电脑,提示出现内部错误,各种常规的设置都已经尝试,感觉公司对此功能进行了限制(我们是集团公司)
  • ¥15 救!ENVI5.6深度学习初始化模型报错怎么办?
  • ¥30 eclipse开启服务后,网页无法打开
  • ¥30 雷达辐射源信号参考模型
  • ¥15 html+css+js如何实现这样子的效果?
  • ¥15 STM32单片机自主设计
  • ¥15 如何在node.js中或者java中给wav格式的音频编码成sil格式呢