Javascript垃圾收集.创建对象和变量?

Tas*_*ons 5 javascript garbage-collection

我目前正在使用Javascript构建游戏.经过一些测试后,我开始注意到偶然的延迟,这只会是由GC引起的.我决定在它上面运行一个配置文件.结果表明GC实际上是罪魁祸首:

GC配置文件

我读到创建新对象会导致很多GC.我想知道是否有这样的事情:

var x = [];
Run Code Online (Sandbox Code Playgroud)

也创建任何Garbage,因为Java中的原始类型不会这样做.由于Javascript中没有真正的类型,我不确定.此外,哪一个最适合创建最少量的垃圾:

选项1:

function do() {
    var x = [];
    ...
}
Run Code Online (Sandbox Code Playgroud)

选项2:

var x = [];
function do() {
    x = [];
    ...
}
Run Code Online (Sandbox Code Playgroud)

选项3:

function do() {
    x = [];
    ...
}
Run Code Online (Sandbox Code Playgroud)

或选项4:

function do() {
    var x = [];
    ...
    delete x;
}
Run Code Online (Sandbox Code Playgroud)

选项5:

var x = [];
function do() {
    x.length = 0;
    ...
}
Run Code Online (Sandbox Code Playgroud)

在我的案例中,do函数被称为30次/秒.它在阵列上运行几个操作.

我想知道这一点,因为我只是将我的所有变量全局化以试图阻止它们被GC收集,但GC没有太大变化.

您是否也可以提供一些常见的例子来说明会产生大量垃圾和一些替代品.

谢谢.

Ste*_*fan 2

能不能也展示一下时间线的记忆?如果您遇到 GC 问题,这些问题应该非常明显,因为您会看到锯齿波图。每当图表下降时,GC 就会启动,阻止您的线程清空垃圾箱,这是内存相关冻结的主要原因

锯齿波图示例(蓝色图为内存):在此输入图像描述

一般来说,您使用哪个对象实例化并不重要,因为 a 对内存的影响[]很小,您感兴趣的是数组的内容,但要仔细检查您的选项:

选项 1:这通常是可以的,但需要考虑一个因素:闭包。您应该尽可能避免闭包,因为它们通常是 GC 的主要原因。

选项 2:避免引用范围之外的内容,它对内存没有帮助,而且会使您的应用程序变慢一些,因为它必须沿着闭包链向上查找匹配项。这样做没有任何好处

选项3:永远不要这样做,你总是想x在某个地方定义,否则你会故意泄漏到全局范围,因此它可能永远不会被GCed

选项4:这实际上是一个有趣的选项。通常delete x不做任何事情,因为delete只作用于对象的属性。如果您不知道,delete实际上返回一个布尔值,表示该对象是否已被删除,因此您可以在 chrome 控制台中运行此示例:

function tmp () {
    var a = 1;
    delete a; // false
    console.log('a=', a) // 1

    b = 2;
    delete b; // true !!!
    console.log('b=', b) // Exception
}
tmp();
Run Code Online (Sandbox Code Playgroud)

什么?!好吧,当你说b = 2(没有var)时,这与写作是一样的window.b = 2,所以当你是 时delete b,你基本上是在delete window.b满足“仅删除属性条款”。不过,不要这样做!

选项 5:这个实际上可以为您节省一点点内存,因为它不需要 GC x,但是:它确实必须 GC 所有内容,其大小x通常比本身大得多,x因此它不会生成不同之处

如果您想了解有关内存分析和常见内存性能陷阱的更多信息,这是一篇很棒的文章:http ://www.smashingmagazine.com/2012/11/writing-fast-memory-efficient-javascript/