我注意到在尝试创建许多Float32Arrays
时出现此错误:
未捕获的RangeError:数组缓冲区分配失败
我试图像这样重现错误:
console.log("trying to cause memory leaks");
for(var i = 0; i < 1000; i++){
console.log(i);
var x = new Float32Array(100000000);
//var x = new Array(100000000);
}
console.log("finished");
据我了解垃圾收集器的概念,他应该收集并转储未链接的对象。但由于我得到上面提到的错误,我不认为它按预期工作。然而,当我使用Array
而不是Float32Array
做同样的事情时,没有任何问题。我甚至可以使用Array
来扩展数字。
所以也许我对垃圾收集器不了解或者Float32Array
构造函数有些可疑。也许我的测试缺乏完整性,即。垃圾收集器没有足够的时间收集,或者像这样琐碎?
也许有人可以给我一些见解?
PS:我使用的是使用V8引擎的Chrome 52.0.2743.116 m
答案 0 :(得分:2)
然而,当我使用
Array
而不是Float32Array
执行相同操作时,没有任何问题。我甚至可以使用Array
来扩展数字。
new Array(100000000)
除了具有length
属性的数组对象外,不会分配任何内容。就是这样。没有创建任何元素插槽,因为标准数组aren't really arrays at all (我博客上发布的帖子),它们只是Array.prototype
支持的特殊对象length
属性以及对名称符合规范&#34;数组索引&#34;的定义的属性的特殊处理(详见the spec)。
相反,new Float32Array(100000000)
必须为100,000,000个32位插槽(加上对象开销)分配连续内存。因此,如果没有可用于该缓冲区的400,000,000字节的连续块,它将会失败。
附注:我能够在* nix上的Chrome 52.0.2743.116(64位)中完成循环。花了一段时间,但......没有出现内存泄漏,系统内存使用在运行时看起来像这样(开始时的平坦线是在我开始之前,我在它完成之前很久就把它切掉了,它将方式太宽,否则):
我们可以看到V8(Chrome中的JavaScript引擎)会让一些垃圾堆积,然后运行GC并清理一些未引用的Float32Array
,然后让垃圾堆积,然后GC等等。没有泄漏
Chrome的任务管理器显示了这种用法:
Before starting: 58,000k While running: 3,700,000 - 5,100,000k At end: 450,000,
...这是有道理的,因为在循环结束时没有清除x
,所以它仍然引用最后一个数组。