繁体   English   中英

JavaScript类型的内存分配

[英]Memory allocation for JavaScript types

我正在尝试优化我正在处理的移动应用程序的地狱,我想知道占用最小内存占用的内容(我意识到这可能因浏览器而异):

  • 对象指针
  • 布尔文字
  • 数字文字
  • 字符串文字

从理论上讲,这应该占用最少的内存空间?

在V8上:

Boolean,number,string,null和void 0 literals将常量的4/8字节的内存用于指针或嵌入指针的立即整数值。 但是根本没有堆分配,因为字符串文字将被内化。 异常可以是大整数或双精度,其中框指针为4/8字节,框为12-16字节。 在优化的代码中,本地双精度数可以在寄存器或堆栈中保持未装箱,或者总是包含双精度数组的数组将存储它们未装箱。

考虑生成的代码的内容:

function weird(d) {
    var a = "foo";
    var b = "bar";
    var c = "quz";

    if( d ) {
        sideEffects(a, b, c);
    }
}

如您所见,指向字符串的指针是硬编码的,不会发生分配。

对象标识至少需要12/24字节用于普通对象,16/32字节用于数组,32/72用于函数(如果需要分配上下文对象,则为+ ~30 / 60字节)。 如果你运行前沿v8并且标识没有转义为无法内联的函数,那么你只能在没有堆分配的情况下离开。

例如:

function arr() {
    return [1,2,3]
}

值1,2,3的后备数组将由函数返回的所有数组共享为写时复制数组,但仍需要为每个数组分配唯一的标识对象。 看看生成的代码有多复杂。 因此,即使使用此优化,如果您不需要数组的唯一标识,只需从上部范围返回一个数组,将避免每次调用该函数时为标识分配:

var a = [1,2,3];
function arr() {
    return a;
}

更简单。

如果你有js的内存问题而没有做任何看似疯狂的事情,你肯定会动态创建函数。 将所有功能提升到不需要重新创建的级别。 从上面可以看出,只有函数的身份才非常胖,因为大多数代码都可以通过利用this来逃避静态函数。

因此,如果您想从中获取任何内容,如果您的目标是性能,请避免非IIFE关闭。 显示它们不是问题的任何基准都是破碎的基准。

您可能有直觉认为,当您拥有8GB时,额外的内存使用情况会有什么影响。 好吧,它在C中没关系。但是在Javascript中,内存不只是坐在那里,它被垃圾收集器跟踪。 位于那里的内存和对象越多,性能就越差。

只需考虑运行如下:

var l = 1024 * 1024 * 2
var a = new Array(l);

for( var i = 0, len = a.length; i < len; ++i ) {
    a[i] = function(){};
}

使用--trace_gc --trace_gc_verbose --print_cumulative_gc_stat 看看有多少工作没有做任何事情。

与静态功能比较:

var l = 1024 * 1024 * 2
var a = new Array(l);
var fn = function(){};

for( var i = 0, len = a.length; i < len; ++i ) {
    a[i] = fn;
}

“文字”表示代码(即使不在字符串序列化中),这是一种更复杂的类型,因此会比值花费更多的空间。

从理论上讲,布尔值可以占用最少的空间,因为它们适合一个位。 虽然任何发动机都不会对此进行优化,但它不太可能。 如果要强制执行此操作,可以手动执行此操作并使用类型化数组进行操作。

但是,性能是实用的,你只能测试,测试,测试它。 如您所知,没有明确的跨浏览器跨版本答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM