【问题标题】:Memory Inefficiency of the Javascript ArrayJavascript 数组的内存效率低下
【发布时间】:2014-05-04 01:55:14
【问题描述】:

我正在编写一个用于可视化数据的浏览器应用程序。有非常大量的数据(数百万行,每行可能有几十个值),在大多数语言中可以以边际开销存储。 Javascript 似乎将数据存储在比所需空间多几倍的空间中,而不管浏览器如何,我已将其范围缩小到数组实现。下面是一个比较 1000 万个数字与 1000 万个数组的内存存储的示例:

默认用法:

火狐:90Mb

铬:30Mb

IE:10Mb


数字:

arr = new Array();
for (var i = 0; i < 10000000; i++) {
    arr.push(1);
}

Firefox:170Mb - 90Mb = 80Mb = 每个值约 8 个字节

Chrome:140Mb - 30Mb = 110Mb = 每个值约 11 个字节

IE:90Mb - 10Mb = 80Mb = 每个值约 8 个字节


数组:

arr = new Array();
for (var i = 0; i < 10000000; i++) {
    arr.push(new Array());
}

Firefox:970Mb - 90Mb = 880Mb = 每个空数组约 88 个字节

Chrome:550Mb - 30Mb = 520Mb = 每个空数组约 52 个字节

IE:930Mb - 10Mb = 920Mb = 每个空数组约 92 个字节


有没有人对这种大量内存使用有任何解释,更重要的是,有没有人有任何解决方案?有一些方法可以解决这个问题,但是为每一行使用一个数组会使数据更容易处理。希望有一个解决方案,因为存储 1000 万行数据需要千兆字节的开销,这太荒谬了。

【问题讨论】:

  • 您正在处理什么样的数据?你考虑过typed arrays吗?
  • 奇怪地看到 IE 赢得了一些东西。 :P 编辑:等等,不,它实际上并没有赢得阵列内存开销战争。
  • @Cory 你考虑过惰性求值吗?内存中有数百万个数组——这听起来不像你想要的任何语言,真的。如果你正在做数据可视化,也许有一种方法可以只使用你当时需要的东西。您可能会考虑使用像 Lazy.js 这样的库,特别是如果您计划对这些数据进行大量处理。
  • 尝试像这样初始化你的数组:arr = new Array(10000000);。现代 JS 引擎可以在预先知道数组的大小和类型时进行优化。此外,如果引擎可以保证每个成员中的数据类型相同,他们也可以利用这一点。
  • 我尝试使用文字语法[] 而不是new Array(),这一次,我的浏览器没有崩溃。 @Cory,这对你有影响吗? (编辑:好的,浏览器没有崩溃 = 它只是冻结。太好了。)

标签: javascript arrays performance memory


【解决方案1】:

我刚刚在 OS X 上的 Chrome 版本 33.0.1750.152 上的 JS 控制台中运行了这个代码块:

arr = new Array();
for (var i = 0; i < 10000000; i++) {
    arr.push(1);
}

我的内存配置文件从 52.1 MB 变为 68.4 MB = 16 MB,每个阵列约 1.6 字节。

当我看到浏览器闲置时,内存配置文件增加了 0.2 MB,但现在似乎保持稳定。

我在控制台上的 Safari 中运行了相同的代码,内存配置文件实际上略有下降,这表明浏览器的内存配置文件与分配给数组的存储空间关系不大,而与其他任何事情有关在应用程序中打开。

更新:

从 22.6 MB 的 Safari Web 内容开始,我加载了这个页面:

<html>
<head>

<script>

    function gen(){

        var arr = new Array();
        for (var i = 0; i < 10000000; i++) {
            arr.push(new Array());
        }
        return arr.length;
    }
</script>


</head>
<body onload="alert(gen())">

</body>
</html>

Safari Web 内容从 22.6 MB 增加到 656.7 MB,然后在警报触发后又回落到 22.8 MB。似乎每个数组都分配了一定数量的 RAM,无论它是否有任何东西,这对我来说很有意义,因为在 Javascript 中,数组是 Object 的子类。

【讨论】:

  • 罗伯特,你没有错 - 但这不是一个数组数组,正如 OP 测试的那样。
  • 我不知道控制台的事。这很酷。我在控制台的第二台计算机上尝试了它,那里也存在大量内存。我怀疑 Windows 与 OSX 会产生很大的不同。也许不同的浏览器设置?我会尝试寻找一些东西。
  • @Robert Chrome 不喜欢我尝试这样做 - 我尝试使用数组文字 [] 但我的实例冻结了。如果您使用数组文字与new Array(),结果会有所不同吗?目前,好奇心胜过我。
  • @lunchmeat,Chrome 似乎也可以使用 arr.push([]) 。我会注意到 Google Chrome Helper 内存配置文件在回落到 40 MB 之前上升到 324 MB,而 Google Chrome 进程本身保持不变。这些代码都没有导致我崩溃。
  • gen 函数创建的数组没有保存在内存中,会被垃圾回收。这就是警报触发后您的内存回落到约 22 MB 的原因。
猜你喜欢
  • 2012-01-11
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 2021-03-24
  • 1970-01-01
  • 2021-05-10
  • 1970-01-01
  • 2016-12-04
相关资源
最近更新 更多