Node.js 中的外部内存与堆内存 - 是否有某种方式的权衡?

jfr*_*d00 5 arrays memory-management node.js

在node.js中,node.js堆中分配的内存与报告为“外部”的内存之间有什么区别process.memoryUsage()?一种相对于另一种有优点或缺点吗?如果您要拥有一个特别大的对象(千兆字节),那么使用哪个对象重要吗?该医生只说了这一点:

external 指的是与 V8 管理的 JavaScript 对象绑定的 C++ 对象的内存使用情况。

它没有告诉您使用此“外部”内存而不是堆内存进行分配可能会产生什么后果或权衡。

我正在研究使用大型数组(常规 Javascript 数组对象)与大型 Uint32Array 对象之间的权衡。显然,数组总是在堆中分配,但 Uint32Array 总是从“外部”内存(不在堆中)分配。

这里是背景。我有一个对象需要相当大的 32 位整数数组作为其功能的一部分。该阵列的长度可达十亿个单位。我意识到,如果我切换到 Uint32Array 而不是常规数组,我可以将数组占用的存储空间减少一半,因为常规数组将数据存储为双精度浮点数(64 位长),而 Uint32Array 将数据存储为 32 位值。

在测试夹具中,我测量到 Uint32Array 确实使用了相同数量单元长度(每个单元 32 位而不是每个单元 64 位)总存储量的 1/2。但是,在查看 的结果时process.memoryUsage(),我注意到 Uint32Array 存储位于“外部”存储桶中,而数组位于“heapUsed”存储桶中。

要添加更多内容,因为 Uint32Array 不可调整大小,当我确实需要更改其大小时,我必须分配一个新的 Uint32Array,然后从原始数据复制数据(我认为这可能会导致更多内存碎片)机会)。使用数组,您只需更改大小,JS 引擎就会处理内部发生的任何事情以调整到新的大小。

在“外部”与“堆”中进行大型存储分配有哪些优点/缺点?有什么理由关心吗?

小智 0

堆用于纯 JavaScript 对象,例如数组、对象、字符串等。它是垃圾收集管理的空间,支持所有混合在一起的所有其他类型。正如您所看到的,外部空间用于存储二进制数据。您可以将它用于其他事情(例如在工作线程之间发送数据)图像处理等。

将各种 TypedArray 视为内存中连续的二进制数据块是很有用的,而 JS 数组将存储为其他结构。这是它们拥有更大内存占用的一个重要原因。您不会使用 TypedArray 获得诸如推送、弹出、移位或调整大小之类的操作,因为您本质上只是在使用一段内存,并且访问只是索引 * int 大小。

如果你知道你只会存储 32 位整数,像 Uint32Array 这样的东西是有意义的,你不需要标准数组,因为它不需要另外具有突然存储随机形状对象的灵活性。这些整数。