首页 > 解决方案 > 2018 年,谷歌的一位技术主管表示,他们正在努力在 64 位系统上的 V8 中“支持超过 4GiB 的缓冲区”。那发生了吗?

问题描述

2018 年,谷歌的一位技术主管表示,他们正在努力在 64 位系统上的 V8 中“支持超过 4GiB 的缓冲区”。那发生了吗?

尝试将大文件加载到缓冲区中,例如:

const fileBuffer = fs.readFileSync(csvPath);

在节点 v12.16.1 中并收到错误:

RangeError [ERR_FS_FILE_TOO_LARGE]: File size (3461193224) is greater than possible Buffer: 2147483647 bytes.

并在 Node v14.12.0 (latest) 中出现错误:

RangeError [ERR_FS_FILE_TOO_LARGE]: File size (3461193224) is greater than 2 GB

由于 32 位整数用于寻址缓冲区,这在我看来是一个限制。但我不明白为什么这会限制 64 位系统......是的,我意识到我可以使用流或从特定地址的文件中读取,但我有大量的内存,而且我限制为 2147483647 字节,因为 Node 仅限于 32 位寻址?

当然,将高频随机访问数据集的缓冲区完全加载到缓冲区中而不是流式传输具有性能优势。引导请求从多缓冲区替代结构中提取所涉及的代码将花费一些东西,无论多么小......

我可以使用该--max-old-space-size=16000标志来增加 Node 使用的最大内存,但我怀疑这是基于 V8 架构的硬限制。但是我仍然要问,因为 Google 的技术负责人确实声称他们将最大缓冲区大小增加到超过 4GiB:2020 年有没有办法在 Node.js 中拥有超过 2147483647 字节的缓冲区?

编辑,谷歌关于该主题的相关跟踪器,显然他们至少从去年开始就在努力解决这个问题https ://bugs.chromium.org/p/v8/issues/detail?id=4153

标签: node.jsv8

解决方案


那发生了吗?

是的,V8 现在支持非常大(许多 GB)的 ArrayBuffer。

有没有办法在 Node.js 中有超过 2147483647 字节的缓冲区?

是的:

$ node
Welcome to Node.js v14.12.0.
Type ".help" for more information.
> let b = Buffer.alloc(3461193224)
undefined
> b.length
3461193224

也就是说,它似乎fs.readFileAsync有自己的限制:https ://github.com/nodejs/node/blob/master/lib/internal/fs/promises.js#L5 我不知道要解除它需要什么。我建议您在 Node 的错误跟踪器上提交问题。

FWIW,Buffer还有另一个限制:

> let buffer = require("buffer")
undefined
> buffer.kMaxLength
4294967295

同样,这是 Node 的决定,而不是 V8 的决定。


推荐阅读