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

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 04: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
      }
    }
    

    这样也可以。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
    wax5798 2022-01-25 07:46

    感谢你的解答

    另外,想请教一下,如果我想把两个文件拼接之后发送,应该怎么处理呢

    回复
    Daniel Tan 回复 wax5798 2022-01-25 16:18

    要看是什么文件,可以考虑直接cat了发,是txt之类的把行列合并就可以了 nodejs可以用readline一行一行读取

    回复
查看更多回答(3条)
编辑
预览

报告相同问题?

问题事件

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

悬赏问题

  • ¥15 C#i编程中so-ir-192编码的字符集转码UTF8问题
  • ¥15 51嵌入式入门按键小项目
  • ¥30 海外项目,如何降低Google Map接口费用?
  • ¥15 fluentmeshing
  • ¥15 手机/平板的浏览器里如何实现类似荧光笔的效果
  • ¥15 盘古气象大模型调用(python)
  • ¥15 传人记程序做的plc 485从机程序该如何写
  • ¥15 已知手指抓握过程中掌指关节、手指各关节和指尖每一帧的坐标,用贝塞尔曲线可以拟合手指抓握的运动轨迹吗?
  • ¥50 libwebsockets 如何添加其他socket事件回调
  • ¥50 实现画布拖拽算子排布,通过flink实现算子编排计算,请提供思路
手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部