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

时间:2015-10-24 11:12:47

标签: javascript garbage-collection

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

GC Profile

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

var x = [];

也会创建任何垃圾,因为Java中的基本类型不会这样做。由于Javascript中没有真正的类型,我不确定。此外,其中哪一项最适合创造最少量的垃圾:

选项1:

function do() {
    var x = [];
    ...
}

选项2:

var x = [];
function do() {
    x = [];
    ...
}

选项3:

function do() {
    x = [];
    ...
}

或选项4:

function do() {
    var x = [];
    ...
    delete x;
}

选项5:

var x = [];
function do() {
    x.length = 0;
    ...
}

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

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

您是否还可以提供一些常见的例子,说明可以创建大量垃圾和一些替代品。

谢谢。

1 个答案:

答案 0 :(得分:2)

你还可以展示时间轴的记忆吗?如果你有GC问题那些那些应该是明显的,因为你会看到一个锯齿波图。每当图表下降时,GC就会启动,阻止你的线程清空我们的垃圾,这是导致内存相关冻结的主要原因

锯齿波图示例(蓝图是记忆):enter image description here

一般来说,你使用哪个对象实例化并不重要,因为[]的内存影响很小,你感兴趣的是数组的内容,但要通过你的选择:

选项1:这通常没问题,只考虑一下:闭包。您应该尽可能地避免关闭,因为它们通常是GC的主要原因。

选项2:避免引用范围之外的内容,它对内存没有帮助,并且它会使您的应用程序变慢,因为它必须通过关闭链来查找比赛。这样做没有好处

选项3:永远不会这样做,您总是希望在某处定义x,否则您会故意泄漏到全局范围内,因此它可能永远不会被GCed < / p>

选项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();

什么?!好吧,当你说b = 2(没有var)时,它与写window.b = 2的内容相同,所以当你delete b时,你就是{&1;}。基本上做delete window.b满足&#34;只删除属性子句&#34;。 不过,不要这样做!

选项5:这个实际上可以节省一点点内存,因为它不需要GC x,但是它确实需要GC所有内容x的{​​{1}}通常比x本身大得多,因此它不会产生影响

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