use*_*679 6 javascript memory performance
我正在尝试优化我正在处理的移动应用程序的地狱,我想知道占用最小内存占用的内容(我意识到这可能因浏览器而异):
从理论上讲,这应该占用最少的内存空间?
Esa*_*ija 16
在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);
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,指向字符串的指针是硬编码的,不会发生分配.
对象标识至少需要12/24字节用于普通对象,16/32字节用于数组,32/72用于函数(如果需要分配上下文对象,则为+ ~30/60字节).如果你运行前沿v8并且标识没有转义为无法内联的函数,那么你只能在没有堆分配的情况下离开.
例如:
function arr() {
return [1,2,3]
}
Run Code Online (Sandbox Code Playgroud)
值1,2,3的后备数组将由函数返回的所有数组共享为写时复制数组,但仍需要为每个数组分配唯一的标识对象.看看生成的代码有多复杂.因此,即使使用此优化,如果您不需要数组的唯一标识,只需从上部范围返回一个数组将避免每次调用该函数时为标识分配:
var a = [1,2,3];
function arr() {
return a;
}
Run Code Online (Sandbox Code Playgroud)
如果你有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(){};
}
Run Code Online (Sandbox Code Playgroud)
随着--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;
}
Run Code Online (Sandbox Code Playgroud)