【问题标题】:Memory allocation for JavaScript typesJavaScript 类型的内存分配
【发布时间】:2013-09-29 00:20:04
【问题描述】:

我正在尝试优化我正在开发的移动应用程序,我想知道什么占用了最小的内存占用(我意识到这可能因浏览器而异):

  • 对象指针
  • 布尔字面量
  • 数字字面量
  • 字符串字面量

理论上哪个应该占用最少的内存空间?

【问题讨论】:

  • 我的猜测是一个空字符串文字。
  • @DesertIvy 仅用于带宽优化。
  • “优化”是一个相对术语。在文字上保存几个字节不会为您节省太多内存(除非您有大量内存),但如果解释器必须将值强制转换为其他形式,则会花费执行时间。
  • 被否决 -3 次?看起来普通的 JavaScript 开发人员对浏览器的内部运作几乎没有好奇心,哇。
  • 我认为反对者应该添加 cmets 来帮助提问者改进这个问题。这听起来很有希望,IMO,尽管可能需要更多细节。例如,哪些部分需要优化?提问者是否对应用程序进行了分析,以确定它肯定是内存占用问题? @user2800679 你怎么知道你需要让你的对象更小来提高你的性能与其他方法相比?您要构建什么样的应用程序?

标签: javascript performance memory


【解决方案1】:

在 V8 上:

布尔值、数字、字符串、null 和 void 0 字面量为指针或嵌入在指针中的立即整数值占用恒定的 4/8 字节内存。但是这些根本没有堆分配,因为字符串文字只会被内部化。例外可以是大整数或双精度数,它们用 4/8 字节的盒子指针和 12-16 字节的盒子装箱。在优化的代码中,本地双精度值可以在寄存器或堆栈中保持未装箱状态,或者始终仅包含双精度值的数组将它们未装箱存储。

考虑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;
}

Much simpler.

如果你在 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_statJust 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;
}

【讨论】:

【解决方案2】:

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

理论上,布尔值占用的空间最少,因为它们适合单个位。尽管任何引擎都不太可能对此进行优化。如果您想强制执行此操作,您可以手动执行此操作并使用类型化数组进行处理。

然而,性能是一个实用的东西,你只能测试、测试、测试它。如您所知,没有明确的跨浏览器跨版本答案。

【讨论】:

    猜你喜欢
    • 2012-03-08
    • 2012-08-06
    • 1970-01-01
    • 2016-04-03
    • 1970-01-01
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多