saf*_*f32 11 javascript memory v8 typed-arrays
我试图减少javascript Web应用程序的内存使用量,该应用程序以大量小字符串的形式在内存中存储大量信息.当我更改代码Uint8Array而不是使用时String,我注意到内存使用率上升了.
例如,请考虑以下创建许多小字符串的代码:
// (1000000 strings) x (10 characters)
var a=[];
for (let i=0; i<1000000; i++)
a.push("a".repeat(10).toUpperCase());
Run Code Online (Sandbox Code Playgroud)
如果你将它放在一个空白的页面中并让内存使用量稳定几秒钟,它就会在谷歌Chrome上稳定在70 MiB.另一方面,以下代码:
// (1000000 arrays) x (10 bytes)
var a=[];
for (let i=0; i<1000000; i++)
a.push(new Uint8Array(10));
Run Code Online (Sandbox Code Playgroud)
使用233 MiB的内存.没有任何代码的空页使用大约20 MiB.另一方面,如果我创建少量的大字符串/数组,差异会变小,而对于单个字符串/数组,具有10000000个字符/条目,内存使用情况几乎相同.
那么为什么类型化数组会有如此大的内存开销呢?
jmr*_*mrk 12
V8开发人员在这里.您的结论是有道理的:如果将字符串中的字符与Uint8Array中的元素进行比较,则字符串将减少开销.TypedArrays非常适合快速访问类型化元素; 但是,拥有大量小型TypedArrays并不具有内存效率.
区别在于字符串和类型化数组的对象标头大小.
对于字符串,对象标题是:
其中有效负载向上舍入到指针大小对齐,在这种情况下为16个字节.
对于Uint8Array,您需要以下内容:
嵌入场#2
数组缓冲区:隐藏类指针
数组缓冲区:嵌入字段#2
元素对象:隐藏类指针
其中,有效负载再次向上舍入到指针大小对齐,因此这里消耗16个字节.
总之,每个字符串消耗5*8 = 40个字节,每个类型化数组消耗26*8 = 208个字节.这似乎是很多开销; 原因是由于TypedArrays提供了各种灵活的选项(它们可以是重叠的视图到ArrayBuffers,可以直接从JavaScript分配,或与WebGL和诸如此类共享等).
(这不是"优化内存分配",也不是"更好地处理垃圾收集字符串" - 因为你坚持使用所有对象,GC不起作用.)
| 归档时间: |
|
| 查看次数: |
2089 次 |
| 最近记录: |