Javascript 空数组与未定义变量的内存开销?

Javascript 空数组与未定义变量的内存开销?,javascript,memory,Javascript,Memory,(假设Arr1开始时是一个未定义的var,然后根据需要变成一个数组。) 十亿Arr1的内存占用是否与十亿Arr2相同?从技术上讲,它们都是空的,但Arr2是一个对象,这意味着对象本身的定义中一定有一些开销,对吗?var Arr1创建了一个内存占用,其中不包含任何引用。所以,是的,这是有成本的,但它是最小的 但是,var Arr2=[]创建了一个内存地址,该地址保存了对新数组对象的引用,因此这里有更多的内存占用。即使数组是空的,它也是array对象的唯一实例,该对象本身使用单个array.prot

(假设Arr1开始时是一个未定义的var,然后根据需要变成一个数组。)


十亿Arr1的内存占用是否与十亿Arr2相同?从技术上讲,它们都是空的,但Arr2是一个对象,这意味着对象本身的定义中一定有一些开销,对吗?

var Arr1
创建了一个内存占用,其中不包含任何引用。所以,是的,这是有成本的,但它是最小的


但是,
var Arr2=[]
创建了一个内存地址,该地址保存了对新数组对象的引用,因此这里有更多的内存占用。即使数组是空的,它也是
array
对象的唯一实例,该对象本身使用单个
array.prototype
从中继承。真正占用内存的是阵列的数量,因为即使是10亿个空阵列也不必存储
Array.prototype
尚未存储的任何内容。即使有10亿个空数组,它们都只从一个
数组继承。prototype
对象,这就是存储数组的本机API的地方。

var Arr1
创建了一个内存占用空间,其中不包含任何引用。所以,是的,这是有成本的,但它是最小的


但是,
var Arr2=[]
创建了一个内存地址,该地址保存了对新数组对象的引用,因此这里有更多的内存占用。即使数组是空的,它也是
array
对象的唯一实例,该对象本身使用单个
array.prototype
从中继承。真正占用内存的是阵列的数量,因为即使是10亿个空阵列也不必存储
Array.prototype
尚未存储的任何内容。即使有10亿个空数组,它们都只从一个
数组.prototype
对象继承,而该对象就是存储数组本机API的地方。

TL;DR:大约90字节


我在Firefox和Chrome上做了一些测量(都在Windows上,64位)。Firefox的精确性要归功于:内存,但你在Chrome中得到的印象也很清楚。(在加载页面并等待页面稳定后,我进行了几次测量,然后取了其中最好的一次。)

我的测试文档只包含一个doctype和一个脚本块

  • 基线(无阵列):

    var Arr1;
    var Arr2 = [];
    
    var x = [];
    for (var i = 0; i < 1000000; i++) {
        x.push(undefined);  // or x.push(null)
    }
    
    Firefox:js领域内存使用量为8.1MB,其中类(数组)/对象为8.00MB,全部为malloc堆。(这表明它为包含数组的一百万个索引中的每一个分配了一个单词。)

    Chrome:选项卡的内存占用为31020K。(听起来每个
    未定义的
    大约有10个字节)

  • 一百万个阵列:

    var Arr1;
    var Arr2 = [];
    
    var x = [];
    for (var i = 0; i < 1000000; i++) {
        x.push(undefined);  // or x.push(null)
    }
    
    var x=[];
    对于(变量i=0;i<1000000;i++){
    x、 推送([]);
    }
    
    Firefox:js领域内存使用量为99.65MB,其中类(数组)/对象为99.55MB,其中91.55MB为gc堆,8.00MB为malloc堆。听起来每个空数组大约96个字节(12个字)

    Chrome:选项卡的内存占用为116164K。与Firefox的开销大致相同


这样看来,与使用
未定义的
空的
TL相比,每个
[]
的开销大约为90字节;DR:
大约90字节


我在Firefox和Chrome上做了一些测量(都在Windows上,64位)。Firefox的精确性要归功于:内存,但你在Chrome中得到的印象也很清楚。(在加载页面并等待页面稳定后,我进行了几次测量,然后取了其中最好的一次。)

我的测试文档只包含一个doctype和一个脚本块

  • 基线(无阵列):

    var Arr1;
    var Arr2 = [];
    
    var x = [];
    for (var i = 0; i < 1000000; i++) {
        x.push(undefined);  // or x.push(null)
    }
    
    Firefox:js领域内存使用量为8.1MB,其中类(数组)/对象为8.00MB,全部为malloc堆。(这表明它为包含数组的一百万个索引中的每一个分配了一个单词。)

    Chrome:选项卡的内存占用为31020K。(听起来每个
    未定义的
    大约有10个字节)

  • 一百万个阵列:

    var Arr1;
    var Arr2 = [];
    
    var x = [];
    for (var i = 0; i < 1000000; i++) {
        x.push(undefined);  // or x.push(null)
    }
    
    var x=[];
    对于(变量i=0;i<1000000;i++){
    x、 推送([]);
    }
    
    Firefox:js领域内存使用量为99.65MB,其中类(数组)/对象为99.55MB,其中91.55MB为gc堆,8.00MB为malloc堆。听起来每个空数组大约96个字节(12个字)

    Chrome:选项卡的内存占用为116164K。与Firefox的开销大致相同


这样看来:与使用
未定义的
null
相比,每个
[]
的开销大约为90字节。使用不同的语言,但使用相同的过程:真正的问题应该是什么应用程序设计要求内存中有数千个未使用的数组?@ste2425:没关系。在考虑效率的情况下进行设计时,我们总是去研究边界条件,看看在极端情况下会发生什么。但是,我也可以给你举个例子:假设我们有一个WebGL游戏,其中每个屏幕对象都可以是直线、多段线、曲线和曲面的集合,但假设今天所有屏幕对象恰好是100万个曲面,所以我们不想要未使用的直线/多段线/曲线,对象属性会给内存占用增加太多。语言不同,但过程相同:真正的问题应该是什么应用程序设计要求内存中有数千个未使用的数组?@ste2425:没关系。在考虑效率的情况下进行设计时,我们总是去研究边界条件,看看在极端情况下会发生什么。但是,我也可以给你举个例子:假设我们有一个WebGL游戏,其中每个屏幕对象可以是直线、多段线、曲线和曲面的集合,但是假设今天所有屏幕对象恰好是100万个曲面,所以我们不想要未使用的直线/多边形