我正在尝试优化我正在开发的移动应用程序,我想知道占用最小内存的内容(我意识到这可能因浏览器而异):
- 对象指针
- bool 字面量
- 数字字面量
- 字符串字面量
理论上哪个应该占用最少的内存空间?
最佳答案
在 V8 上:
bool 值、数字、字符串、null 和 void 0 字面量为指针或嵌入在指针中的立即整数值占用恒定的 4/8 字节内存。但是这些根本没有堆分配,因为字符串文字只会被内部化。异常(exception)可以是大整数或 double ,它们用 4/8 字节的盒子指针和 12-16 字节的盒子装箱。在优化的代码中,本地 double 值可以在寄存器或堆栈中保持未装箱状态,或者始终仅包含 double 值的数组将它们未装箱存储。
考虑 the meat of the generated code为:
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 的后备数组将作为写入时复制数组被函数返回的所有数组共享,但对于需要分配的每个数组仍然是唯一的标识对象。看看 generated code is 有多复杂.因此,即使进行了这种优化,如果您不需要数组的唯一标识,只需从上层范围返回一个数组即可避免每次调用函数时分配标识:
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
。 Just look how much work什么都没做。
与静态函数比较:
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;
}
关于javascript - JavaScript 类型的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18970509/