关于node.js:RangeError-Array-buffer-allocation-failed

在应用 Node.js 合并文件分片时呈现了题目的错误信息。

代码剖析

m.merge = (opts) => {
  return new Promise((resolve, reject) => {
    const { filename, target } = opts;
    try {
      let len = 0;
      const bufferList = fs.readdirSync(`${STATIC_TEMPORARY}/${filename}`).map((hash, index) => {
        const buffer = fs.readFileSync(`${STATIC_TEMPORARY}/${filename}/${index}`);
        len += buffer.length;
        return buffer;
      });
      // Merge files
      const buffer = Buffer.concat(bufferList, len);
      const ws = fs.createWriteStream(`${target}/${filename}`);
      ws.write(buffer);
      ws.close();
      resolve({ success: true, msg: 'Section merge completed' });
    } catch (error) {
      console.error(error);
      reject({ success: false, msg: error });
    }
  });
};

const buffer = Buffer.concat(bufferList, len);
定位到是上边这行呈现了问题,查看了一下服务器,node利用的内存占用是 192.1mb。

这时起因就很明了,是因为文件分片太大导致内存耗尽,没有可用空间了。

优化办法

下面的做法是把所有的文件分片都concat而后写到流中,正是在这个过程中导致了内存耗尽。
其实,咱们能够按程序分屡次concat写入,批改代码如下:

m.merge = (opts) => {
  return new Promise((resolve, reject) => {
    const { filename, target } = opts;

    try {
      // 优化
      const ws = fs.createWriteStream(`${target}/${filename}`);
      const bufferList = fs.readdirSync(`${STATIC_TEMPORARY}/${filename}`)
      let len = 0;
      let list = []
      bufferList.forEach((hash, index) => {
        const b = fs.readFileSync(`${STATIC_TEMPORARY}/${filename}/${index}`);
        len += b.length;
        list.push(b)
        if (len > 10485760) { // 10M
          const buffer = Buffer.concat(list, len);
          ws.write(buffer);
          len = 0;
          list = []
        }
      })
      ws.close();
      resolve({ success: true, msg: 'Section merge completed' });
    } catch (error) {
      console.error(error);
      reject({ success: false, msg: error });
    }
  });
};

这是从新调用接口就不会呈现题目的谬误了,文件能够合并胜利。然而查看一下Node过程的内存占用 却依然放弃在192.1mb左右。

这就须要对Node做一下具体的内存剖析了。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理